Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge recent trunk enhancements into the begin-concurrent-pnu branch. |
---|---|
Timelines: | family | ancestors | descendants | both | begin-concurrent-pnu |
Files: | files | file ages | folders |
SHA3-256: |
54930b7e0a585d0db3633673f33cac28 |
User & Date: | drh 2019-09-16 12:17:11.121 |
Context
2019-09-30
| ||
16:43 | Merge version 3.30.0 beta 1 changes from trunk. (check-in: ac4b644268 user: drh tags: begin-concurrent-pnu) | |
2019-09-16
| ||
12:17 | Merge recent trunk enhancements into the begin-concurrent-pnu branch. (check-in: 54930b7e0a user: drh tags: begin-concurrent-pnu) | |
05:34 | Fix a problem with processing CTEs that use a WINDOW clause. (check-in: ca564d4b5b user: dan tags: trunk) | |
2019-07-10
| ||
18:21 | Merge the 3.29.0 changes into the begin-concurrent-pnu branch. (check-in: c89949ccd1 user: drh tags: begin-concurrent-pnu) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
605 606 607 608 609 610 611 | 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_ENABLE_DESERIALIZE | < | 605 606 607 608 609 610 611 612 613 614 615 616 617 618 | 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_ENABLE_DESERIALIZE FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000 FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000 FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4 #FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5 |
︙ | ︙ |
Changes to Makefile.linux-gcc.
︙ | ︙ | |||
15 16 17 18 19 20 21 | # that contains this "Makefile.in" and the "configure.in" script. # TOP = ../sqlite #### C Compiler and options for use in building executables that # will run on the platform that is doing the build. # | | | | | | < < | | < < | < < | < < | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 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 | # that contains this "Makefile.in" and the "configure.in" script. # TOP = ../sqlite #### C Compiler and options for use in building executables that # will run on the platform that is doing the build. # BCC = gcc -g -O0 #BCC = /opt/ancic/bin/c89 -0 #### If the target operating system supports the "usleep()" system # call, then define the HAVE_USLEEP macro for all C modules. # #USLEEP = USLEEP = -DHAVE_USLEEP=1 #### If you want the SQLite library to be safe for use within a # multi-threaded program, then define the following macro # appropriately: # #THREADSAFE = -DTHREADSAFE=1 THREADSAFE = -DTHREADSAFE=0 #### Specify any extra linker options needed to make the library # thread safe # THREADLIB = -lpthread -lm -ldl #THREADLIB = #### Specify any extra libraries needed to access required functions. # #TLIBS = -lrt # fdatasync on Solaris 8 TLIBS = #### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1 # to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all # malloc()s and free()s in order to track down memory leaks. # # SQLite uses some expensive assert() statements in the inner loop. # You can make the library go almost twice as fast if you compile # with -DNDEBUG=1 # OPTS += -DSQLITE_DEBUG=1 OPTS += -DSQLITE_ENABLE_WHERETRACE OPTS += -DSQLITE_ENABLE_SELECTTRACE #### The suffix to add to executable files. ".exe" for windows. # Nothing for unix. # #EXE = .exe EXE = #### C Compile and options for use in building executables that # will run on the target platform. This is usually the same # as BCC, unless you are cross-compiling. # TCC = gcc -O0 #TCC = gcc -g -O0 -Wall #TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage #TCC = /opt/mingw/bin/i386-mingw32-gcc -O6 #TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive #### Tools used to build a static library. # AR = ar cr #AR = /opt/mingw/bin/i386-mingw32-ar cr RANLIB = ranlib #RANLIB = /opt/mingw/bin/i386-mingw32-ranlib MKSHLIB = gcc -shared SO = so SHPREFIX = lib # SO = dll # SHPREFIX = #### Extra compiler options needed for programs that use the TCL library. # TCL_FLAGS = -I/home/drh/tcl/include/tcl8.6 #### Linker options needed to link against the TCL library. # #LIBTCL = -ltcl -lm -ldl LIBTCL = /home/drh/tcl/lib/libtcl8.6.a -lm -lpthread -ldl -lz #### Additional objects for SQLite library when TCL support is enabled. #TCLOBJ = TCLOBJ = tclsqlite.o #### Compiler options needed for programs that use the readline() library. # |
︙ | ︙ |
Changes to Makefile.msc.
︙ | ︙ | |||
69 70 71 72 73 74 75 | # If necessary, create a list of harmless compiler warnings to disable when # compiling the various tools. For the SQLite source code itself, warnings, # if any, will be disabled from within it. # !IFNDEF NO_WARN !IF $(USE_FULLWARN)!=0 NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206 | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | # If necessary, create a list of harmless compiler warnings to disable when # compiling the various tools. For the SQLite source code itself, warnings, # if any, will be disabled from within it. # !IFNDEF NO_WARN !IF $(USE_FULLWARN)!=0 NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206 NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706 !ENDIF !ENDIF # Set this non-0 to use the library paths and other options necessary for # Windows Phone 8.1. # !IFNDEF USE_WP81_OPTS |
︙ | ︙ | |||
347 348 349 350 351 352 353 | 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 | < | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1 !ENDIF OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 !ENDIF # Should the session extension be enabled? If so, add compilation options # to enable it. |
︙ | ︙ |
Changes to VERSION.
|
| | | 1 | 3.30.0 |
Changes to autoconf/Makefile.msc.
︙ | ︙ | |||
69 70 71 72 73 74 75 | # If necessary, create a list of harmless compiler warnings to disable when # compiling the various tools. For the SQLite source code itself, warnings, # if any, will be disabled from within it. # !IFNDEF NO_WARN !IF $(USE_FULLWARN)!=0 NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206 | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | # If necessary, create a list of harmless compiler warnings to disable when # compiling the various tools. For the SQLite source code itself, warnings, # if any, will be disabled from within it. # !IFNDEF NO_WARN !IF $(USE_FULLWARN)!=0 NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206 NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706 !ENDIF !ENDIF # Set this non-0 to use the library paths and other options necessary for # Windows Phone 8.1. # !IFNDEF USE_WP81_OPTS |
︙ | ︙ |
Changes to configure.
1 2 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. | | | 1 2 3 4 5 6 7 8 9 10 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for sqlite 3.30.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. |
︙ | ︙ | |||
722 723 724 725 726 727 728 | subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' | | | | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' PACKAGE_VERSION='3.30.0' PACKAGE_STRING='sqlite 3.30.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include <stdio.h> #ifdef HAVE_SYS_TYPES_H |
︙ | ︙ | |||
1462 1463 1464 1465 1466 1467 1468 | # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF | | | 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 | # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures sqlite 3.30.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. |
︙ | ︙ | |||
1527 1528 1529 1530 1531 1532 1533 | --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in | | | 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 | --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of sqlite 3.30.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] |
︙ | ︙ | |||
1653 1654 1655 1656 1657 1658 1659 | cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF | | | 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 | cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF sqlite configure 3.30.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit |
︙ | ︙ | |||
2072 2073 2074 2075 2076 2077 2078 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. | | | 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 | eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by sqlite $as_me 3.30.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { |
︙ | ︙ | |||
12228 12229 12230 12231 12232 12233 12234 | test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" | | | 12228 12229 12230 12231 12232 12233 12234 12235 12236 12237 12238 12239 12240 12241 12242 | test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by sqlite $as_me 3.30.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ |
︙ | ︙ | |||
12294 12295 12296 12297 12298 12299 12300 | Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ | | | 12294 12295 12296 12297 12298 12299 12300 12301 12302 12303 12304 12305 12306 12307 12308 | Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ sqlite config.status 3.30.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." |
︙ | ︙ |
Changes to ext/expert/expert1.test.
︙ | ︙ | |||
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | } { SELECT a FROM t1 WHERE a=? ORDER BY b; } { CREATE INDEX t1_idx_000123a7 ON t1(a, b); SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?) } do_setup_rec_test $tn.6 { CREATE TABLE t1(a, b, c); } { SELECT min(a) FROM t1 } { CREATE INDEX t1_idx_00000061 ON t1(a); SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061 } do_setup_rec_test $tn.7 { CREATE TABLE t1(a, b, c); } { SELECT * FROM t1 ORDER BY a, b, c; } { | > > | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | } { SELECT a FROM t1 WHERE a=? ORDER BY b; } { CREATE INDEX t1_idx_000123a7 ON t1(a, b); SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?) } if 0 { do_setup_rec_test $tn.6 { CREATE TABLE t1(a, b, c); } { SELECT min(a) FROM t1 } { CREATE INDEX t1_idx_00000061 ON t1(a); SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061 } } do_setup_rec_test $tn.7 { CREATE TABLE t1(a, b, c); } { SELECT * FROM t1 ORDER BY a, b, c; } { |
︙ | ︙ |
Changes to ext/fts3/fts3_snippet.c.
︙ | ︙ | |||
429 430 431 432 433 434 435 | SnippetPhrase *pPhrase = &pIter->aPhrase[i]; if( pPhrase->pTail ){ char *pCsr = pPhrase->pTail; int iCsr = pPhrase->iTail; while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){ int j; | | | | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | SnippetPhrase *pPhrase = &pIter->aPhrase[i]; if( pPhrase->pTail ){ char *pCsr = pPhrase->pTail; int iCsr = pPhrase->iTail; while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){ int j; u64 mPhrase = (u64)1 << (i%64); u64 mPos = (u64)1 << (iCsr - iStart); assert( iCsr>=iStart && (iCsr - iStart)<=64 ); assert( i>=0 ); if( (mCover|mCovered)&mPhrase ){ iScore++; }else{ iScore += 1000; } mCover |= mPhrase; |
︙ | ︙ |
Changes to ext/fts3/fts3_write.c.
︙ | ︙ | |||
3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 | assert_fts3_nc( (pNode->a[0]=='\0')==(aDoclist!=0) ); blobGrowBuffer(pPrev, nTerm, &rc); if( rc!=SQLITE_OK ) return rc; nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm); nSuffix = nTerm - nPrefix; memcpy(pPrev->a, zTerm, nTerm); pPrev->n = nTerm; if( bFirst==0 ){ pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nPrefix); } pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nSuffix); | > | 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 | assert_fts3_nc( (pNode->a[0]=='\0')==(aDoclist!=0) ); blobGrowBuffer(pPrev, nTerm, &rc); if( rc!=SQLITE_OK ) return rc; nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm); nSuffix = nTerm - nPrefix; if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; memcpy(pPrev->a, zTerm, nTerm); pPrev->n = nTerm; if( bFirst==0 ){ pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nPrefix); } pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nSuffix); |
︙ | ︙ |
Changes to ext/fts5/fts5Int.h.
︙ | ︙ | |||
174 175 176 177 178 179 180 181 182 183 184 185 186 187 | char *zContent; /* content table */ char *zContentRowid; /* "content_rowid=" option value */ int bColumnsize; /* "columnsize=" option value (dflt==1) */ int eDetail; /* FTS5_DETAIL_XXX value */ char *zContentExprlist; Fts5Tokenizer *pTok; fts5_tokenizer *pTokApi; /* Values loaded from the %_config table */ int iCookie; /* Incremented when %_config is modified */ int pgsz; /* Approximate page size used in %_data */ int nAutomerge; /* 'automerge' setting */ int nCrisisMerge; /* Maximum allowed segments per level */ int nUsermerge; /* 'usermerge' setting */ | > | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | char *zContent; /* content table */ char *zContentRowid; /* "content_rowid=" option value */ int bColumnsize; /* "columnsize=" option value (dflt==1) */ int eDetail; /* FTS5_DETAIL_XXX value */ char *zContentExprlist; Fts5Tokenizer *pTok; fts5_tokenizer *pTokApi; int bLock; /* True when table is preparing statement */ /* Values loaded from the %_config table */ int iCookie; /* Incremented when %_config is modified */ int pgsz; /* Approximate page size used in %_data */ int nAutomerge; /* 'automerge' setting */ int nCrisisMerge; /* Maximum allowed segments per level */ int nUsermerge; /* 'usermerge' setting */ |
︙ | ︙ | |||
690 691 692 693 694 695 696 697 698 699 700 701 702 703 | */ int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc); int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax); int sqlite3Fts5ExprEof(Fts5Expr*); i64 sqlite3Fts5ExprRowid(Fts5Expr*); void sqlite3Fts5ExprFree(Fts5Expr*); /* Called during startup to register a UDF with SQLite */ int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*); int sqlite3Fts5ExprPhraseCount(Fts5Expr*); int sqlite3Fts5ExprPhraseSize(Fts5Expr*, int iPhrase); int sqlite3Fts5ExprPoslist(Fts5Expr*, int, const u8 **); | > | 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 | */ int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc); int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax); int sqlite3Fts5ExprEof(Fts5Expr*); i64 sqlite3Fts5ExprRowid(Fts5Expr*); void sqlite3Fts5ExprFree(Fts5Expr*); int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2); /* Called during startup to register a UDF with SQLite */ int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*); int sqlite3Fts5ExprPhraseCount(Fts5Expr*); int sqlite3Fts5ExprPhraseSize(Fts5Expr*, int iPhrase); int sqlite3Fts5ExprPoslist(Fts5Expr*, int, const u8 **); |
︙ | ︙ |
Changes to ext/fts5/fts5_config.c.
︙ | ︙ | |||
679 680 681 682 683 684 685 | ); assert( zSql || rc==SQLITE_NOMEM ); if( zSql ){ rc = sqlite3_declare_vtab(pConfig->db, zSql); sqlite3_free(zSql); } | | | 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 | ); assert( zSql || rc==SQLITE_NOMEM ); if( zSql ){ rc = sqlite3_declare_vtab(pConfig->db, zSql); sqlite3_free(zSql); } return rc; } /* ** Tokenize the text passed via the second and third arguments. ** ** The callback is invoked once for each token in the input text. The |
︙ | ︙ |
Changes to ext/fts5/fts5_expr.c.
︙ | ︙ | |||
304 305 306 307 308 309 310 311 312 313 314 315 316 317 | void sqlite3Fts5ExprFree(Fts5Expr *p){ if( p ){ sqlite3Fts5ParseNodeFree(p->pRoot); sqlite3_free(p->apExprPhrase); sqlite3_free(p); } } /* ** Argument pTerm must be a synonym iterator. Return the current rowid ** that it points to. */ static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){ i64 iRet = 0; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | void sqlite3Fts5ExprFree(Fts5Expr *p){ if( p ){ sqlite3Fts5ParseNodeFree(p->pRoot); sqlite3_free(p->apExprPhrase); sqlite3_free(p); } } int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ Fts5Parse sParse; memset(&sParse, 0, sizeof(sParse)); if( *pp1 ){ Fts5Expr *p1 = *pp1; int nPhrase = p1->nPhrase + p2->nPhrase; p1->pRoot = sqlite3Fts5ParseNode(&sParse, FTS5_AND, p1->pRoot, p2->pRoot,0); p2->pRoot = 0; if( sParse.rc==SQLITE_OK ){ Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc( p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*) ); if( ap==0 ){ sParse.rc = SQLITE_NOMEM; }else{ int i; memmove(&ap[p2->nPhrase], ap, p1->nPhrase*sizeof(Fts5ExprPhrase*)); for(i=0; i<p2->nPhrase; i++){ ap[i] = p2->apExprPhrase[i]; } p1->nPhrase = nPhrase; p1->apExprPhrase = ap; } } sqlite3_free(p2->apExprPhrase); sqlite3_free(p2); }else{ *pp1 = p2; } return sParse.rc; } /* ** Argument pTerm must be a synonym iterator. Return the current rowid ** that it points to. */ static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){ i64 iRet = 0; |
︙ | ︙ |
Changes to ext/fts5/fts5_index.c.
︙ | ︙ | |||
686 687 688 689 690 691 692 693 694 695 696 697 698 699 | } if( rc!=SQLITE_OK ){ sqlite3_free(pRet); pRet = 0; }else{ /* TODO1: Fix this */ pRet->p[nByte] = 0x00; pRet->szLeaf = fts5GetU16(&pRet->p[2]); } } p->rc = rc; p->nRead++; } | > | 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 | } if( rc!=SQLITE_OK ){ sqlite3_free(pRet); pRet = 0; }else{ /* TODO1: Fix this */ pRet->p[nByte] = 0x00; pRet->p[nByte+1] = 0x00; pRet->szLeaf = fts5GetU16(&pRet->p[2]); } } p->rc = rc; p->nRead++; } |
︙ | ︙ | |||
4992 4993 4994 4995 4996 4997 4998 4999 5000 | int nCopy; u8 *aCopy; i64 iPrev = 0; Fts5PoslistWriter writer; memset(&writer, 0, sizeof(writer)); fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); fts5BufferZero(&tmp); | > > > | | 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 | int nCopy; u8 *aCopy; i64 iPrev = 0; Fts5PoslistWriter writer; memset(&writer, 0, sizeof(writer)); /* See the earlier comment in this function for an explanation of why ** corrupt input position lists might cause the output to consume ** at most 20 bytes of unexpected space. */ fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); fts5BufferZero(&tmp); sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist + 10 + 10); if( p->rc ) break; sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); assert_nc( iPos1>=0 && iPos2>=0 ); if( iPos1<iPos2 ){ |
︙ | ︙ | |||
5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 | nCopy = i2.nPoslist - iOff2; } if( nCopy>0 ){ fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy); } /* WRITEPOSLISTSIZE */ fts5BufferSafeAppendVarint(&out, tmp.n * 2); fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); fts5DoclistIterNext(&i1); fts5DoclistIterNext(&i2); assert_nc( out.n<=(p1->n+p2->n+9) ); if( i1.aPoslist==0 || i2.aPoslist==0 ) break; assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) ); | > > > > > > | 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 | nCopy = i2.nPoslist - iOff2; } if( nCopy>0 ){ fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy); } /* WRITEPOSLISTSIZE */ assert_nc( tmp.n<=i1.nPoslist+i2.nPoslist ); assert( tmp.n<=i1.nPoslist+i2.nPoslist+10+10 ); if( tmp.n>i1.nPoslist+i2.nPoslist ){ if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; break; } fts5BufferSafeAppendVarint(&out, tmp.n * 2); fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); fts5DoclistIterNext(&i1); fts5DoclistIterNext(&i2); assert_nc( out.n<=(p1->n+p2->n+9) ); if( i1.aPoslist==0 || i2.aPoslist==0 ) break; assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) ); |
︙ | ︙ |
Changes to ext/fts5/fts5_main.c.
︙ | ︙ | |||
461 462 463 464 465 466 467 | #endif } /* ** Implementation of the xBestIndex method for FTS5 tables. Within the ** WHERE constraint, it searches for the following: ** | | > | | | | > > > > > > > > > > > > > > > > > > > > > | 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 | #endif } /* ** Implementation of the xBestIndex method for FTS5 tables. Within the ** WHERE constraint, it searches for the following: ** ** 1. A MATCH constraint against the table column. ** 2. A MATCH constraint against the "rank" column. ** 3. A MATCH constraint against some other column. ** 4. An == constraint against the rowid column. ** 5. A < or <= constraint against the rowid column. ** 6. A > or >= constraint against the rowid column. ** ** Within the ORDER BY, the following are supported: ** ** 5. ORDER BY rank [ASC|DESC] ** 6. ORDER BY rowid [ASC|DESC] ** ** Information for the xFilter call is passed via both the idxNum and ** idxStr variables. Specifically, idxNum is a bitmask of the following ** flags used to encode the ORDER BY clause: ** ** FTS5_BI_ORDER_RANK ** FTS5_BI_ORDER_ROWID ** FTS5_BI_ORDER_DESC ** ** idxStr is used to encode data from the WHERE clause. For each argument ** passed to the xFilter method, the following is appended to idxStr: ** ** Match against table column: "m" ** Match against rank column: "r" ** Match against other column: "<column-number>" ** Equality constraint against the rowid: "=" ** A < or <= against the rowid: "<" ** A > or >= against the rowid: ">" ** ** This function ensures that there is at most one "r" or "=". And that if ** there exists an "=" then there is no "<" or ">". ** ** Costs are assigned as follows: ** ** a) If an unusable MATCH operator is present in the WHERE clause, the ** cost is unconditionally set to 1e50 (a really big number). ** ** a) If a MATCH operator is present, the cost depends on the other |
︙ | ︙ | |||
499 500 501 502 503 504 505 | ** Costs are not modified by the ORDER BY clause. */ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ Fts5Table *pTab = (Fts5Table*)pVTab; Fts5Config *pConfig = pTab->pConfig; const int nCol = pConfig->nCol; int idxFlags = 0; /* Parameter passed through to xFilter() */ | < < | < < | < | < < < < < < < < < < < | | | > > | > > > > > > | > > > > > < | | | < < < > > > > > > > > > > > > > > | > > > > > > | > > > > > > | > | | | > > > > > | > > > | > > > | < | | | | | | | | < < < < < < < < < < | 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 | ** Costs are not modified by the ORDER BY clause. */ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ Fts5Table *pTab = (Fts5Table*)pVTab; Fts5Config *pConfig = pTab->pConfig; const int nCol = pConfig->nCol; int idxFlags = 0; /* Parameter passed through to xFilter() */ int i; char *idxStr; int iIdxStr = 0; int iCons = 0; int bSeenEq = 0; int bSeenGt = 0; int bSeenLt = 0; int bSeenMatch = 0; int bSeenRank = 0; assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH ); assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH ); assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH ); assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH ); assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH ); if( pConfig->bLock ){ pTab->base.zErrMsg = sqlite3_mprintf( "recursively defined fts5 content table" ); return SQLITE_ERROR; } idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 6 + 1); if( idxStr==0 ) return SQLITE_NOMEM; pInfo->idxStr = idxStr; pInfo->needToFreeIdxStr = 1; for(i=0; i<pInfo->nConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; int iCol = p->iColumn; if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol) ){ /* A MATCH operator or equivalent */ if( p->usable==0 || iCol<0 ){ /* As there exists an unusable MATCH constraint this is an ** unusable plan. Set a prohibitively high cost. */ pInfo->estimatedCost = 1e50; assert( iIdxStr < pInfo->nConstraint*6 + 1 ); idxStr[iIdxStr] = 0; return SQLITE_OK; }else{ if( iCol==nCol+1 ){ if( bSeenRank ) continue; idxStr[iIdxStr++] = 'r'; bSeenRank = 1; }else{ bSeenMatch = 1; idxStr[iIdxStr++] = 'm'; if( iCol<nCol ){ sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol); idxStr += strlen(&idxStr[iIdxStr]); assert( idxStr[iIdxStr]=='\0' ); } } pInfo->aConstraintUsage[i].argvIndex = ++iCons; pInfo->aConstraintUsage[i].omit = 1; } } else if( p->usable && bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){ idxStr[iIdxStr++] = '='; bSeenEq = 1; pInfo->aConstraintUsage[i].argvIndex = ++iCons; } } if( bSeenEq==0 ){ for(i=0; i<pInfo->nConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; if( p->iColumn<0 && p->usable ){ int op = p->op; if( op==SQLITE_INDEX_CONSTRAINT_LT || op==SQLITE_INDEX_CONSTRAINT_LE ){ if( bSeenLt ) continue; idxStr[iIdxStr++] = '<'; pInfo->aConstraintUsage[i].argvIndex = ++iCons; bSeenLt = 1; }else if( op==SQLITE_INDEX_CONSTRAINT_GT || op==SQLITE_INDEX_CONSTRAINT_GE ){ if( bSeenGt ) continue; idxStr[iIdxStr++] = '>'; pInfo->aConstraintUsage[i].argvIndex = ++iCons; bSeenGt = 1; } } } } idxStr[iIdxStr] = '\0'; /* Set idxFlags flags for the ORDER BY clause */ if( pInfo->nOrderBy==1 ){ int iSort = pInfo->aOrderBy[0].iColumn; if( iSort==(pConfig->nCol+1) && bSeenMatch ){ idxFlags |= FTS5_BI_ORDER_RANK; }else if( iSort==-1 ){ idxFlags |= FTS5_BI_ORDER_ROWID; } if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){ pInfo->orderByConsumed = 1; if( pInfo->aOrderBy[0].desc ){ idxFlags |= FTS5_BI_ORDER_DESC; } } } /* Calculate the estimated cost based on the flags set in idxFlags. */ if( bSeenEq ){ pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0; if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo); }else if( bSeenLt && bSeenGt ){ pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0; }else if( bSeenLt || bSeenGt ){ pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0; }else{ pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0; } pInfo->idxNum = idxFlags; return SQLITE_OK; } static int fts5NewTransaction(Fts5FullTable *pTab){ |
︙ | ︙ | |||
921 922 923 924 925 926 927 | ** handles here, rather than preparing a new one for each query. But that ** is not possible as SQLite reference counts the virtual table objects. ** And since the statement required here reads from this very virtual ** table, saving it creates a circular reference. ** ** If SQLite a built-in statement cache, this wouldn't be a problem. */ rc = fts5PrepareStatement(&pSorter->pStmt, pConfig, | | | 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 | ** handles here, rather than preparing a new one for each query. But that ** is not possible as SQLite reference counts the virtual table objects. ** And since the statement required here reads from this very virtual ** table, saving it creates a circular reference. ** ** If SQLite a built-in statement cache, this wouldn't be a problem. */ rc = fts5PrepareStatement(&pSorter->pStmt, pConfig, "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(\"%w\"%s%s) %s", pConfig->zDb, pConfig->zName, zRank, pConfig->zName, (zRankArgs ? ", " : ""), (zRankArgs ? zRankArgs : ""), bDesc ? "DESC" : "ASC" ); pCsr->pSorter = pSorter; |
︙ | ︙ | |||
977 978 979 980 981 982 983 | while( z[0]==' ' ) z++; for(n=0; z[n] && z[n]!=' '; n++); assert( pTab->p.base.zErrMsg==0 ); pCsr->ePlan = FTS5_PLAN_SPECIAL; | | | | 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 | while( z[0]==' ' ) z++; for(n=0; z[n] && z[n]!=' '; n++); assert( pTab->p.base.zErrMsg==0 ); pCsr->ePlan = FTS5_PLAN_SPECIAL; if( n==5 && 0==sqlite3_strnicmp("reads", z, n) ){ pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex); } else if( n==2 && 0==sqlite3_strnicmp("id", z, n) ){ pCsr->iSpecial = pCsr->iCsrId; } else{ /* An unrecognized directive. Return an error message. */ pTab->p.base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z); rc = SQLITE_ERROR; } |
︙ | ︙ | |||
1121 1122 1123 1124 1125 1126 1127 | ** 1. Full-text search using a MATCH operator. ** 2. A by-rowid lookup. ** 3. A full-table scan. */ static int fts5FilterMethod( sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ int idxNum, /* Strategy index */ | | < < | | | > | < | | | < | > | | > | > | > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 | ** 1. Full-text search using a MATCH operator. ** 2. A by-rowid lookup. ** 3. A full-table scan. */ static int fts5FilterMethod( sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ int idxNum, /* Strategy index */ const char *idxStr, /* Unused */ int nVal, /* Number of elements in apVal */ sqlite3_value **apVal /* Arguments for the indexing scheme */ ){ Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab); Fts5Config *pConfig = pTab->p.pConfig; Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; int rc = SQLITE_OK; /* Error code */ int bDesc; /* True if ORDER BY [rank|rowid] DESC */ int bOrderByRank; /* True if ORDER BY rank */ sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */ sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */ sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */ sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ int iCol; /* Column on LHS of MATCH operator */ char **pzErrmsg = pConfig->pzErrmsg; int i; int iIdxStr = 0; Fts5Expr *pExpr = 0; if( pCsr->ePlan ){ fts5FreeCursorComponents(pCsr); memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr)); } assert( pCsr->pStmt==0 ); assert( pCsr->pExpr==0 ); assert( pCsr->csrflags==0 ); assert( pCsr->pRank==0 ); assert( pCsr->zRank==0 ); assert( pCsr->zRankArgs==0 ); assert( pTab->pSortCsr==0 || nVal==0 ); assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg ); pConfig->pzErrmsg = &pTab->p.base.zErrMsg; /* Decode the arguments passed through to this function. */ for(i=0; i<nVal; i++){ switch( idxStr[iIdxStr++] ){ case 'r': pRank = apVal[i]; break; case 'm': { const char *zText = (const char*)sqlite3_value_text(apVal[i]); if( zText==0 ) zText = ""; if( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ){ iCol = 0; do{ iCol = iCol*10 + (idxStr[iIdxStr]-'0'); iIdxStr++; }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ); }else{ iCol = pConfig->nCol; } if( zText[0]=='*' ){ /* The user has issued a query of the form "MATCH '*...'". This ** indicates that the MATCH expression is not a full text query, ** but a request for an internal parameter. */ rc = fts5SpecialMatch(pTab, pCsr, &zText[1]); goto filter_out; }else{ char **pzErr = &pTab->p.base.zErrMsg; rc = sqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); pExpr = 0; } if( rc!=SQLITE_OK ) goto filter_out; } break; } case '=': pRowidEq = apVal[i]; break; case '<': pRowidLe = apVal[i]; break; default: assert( idxStr[iIdxStr-1]=='>' ); pRowidGe = apVal[i]; break; } } bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0); pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0); /* Set the cursor upper and lower rowid limits. Only some strategies ** actually use them. This is ok, as the xBestIndex() method leaves the ** sqlite3_index_constraint.omit flag clear for range constraints ** on the rowid field. */ |
︙ | ︙ | |||
1197 1198 1199 1200 1201 1202 1203 | /* If pSortCsr is non-NULL, then this call is being made as part of ** processing for a "... MATCH <expr> ORDER BY rank" query (ePlan is ** set to FTS5_PLAN_SORTED_MATCH). pSortCsr is the cursor that will ** return results to the user for this query. The current cursor ** (pCursor) is used to execute the query issued by function ** fts5CursorFirstSorted() above. */ assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 ); | | | < < < < < < < < < < < < | | | | | | < < | > > | 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 | /* If pSortCsr is non-NULL, then this call is being made as part of ** processing for a "... MATCH <expr> ORDER BY rank" query (ePlan is ** set to FTS5_PLAN_SORTED_MATCH). pSortCsr is the cursor that will ** return results to the user for this query. The current cursor ** (pCursor) is used to execute the query issued by function ** fts5CursorFirstSorted() above. */ assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 ); assert( nVal==0 && bOrderByRank==0 && bDesc==0 ); assert( pCsr->iLastRowid==LARGEST_INT64 ); assert( pCsr->iFirstRowid==SMALLEST_INT64 ); if( pTab->pSortCsr->bDesc ){ pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid; pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid; }else{ pCsr->iLastRowid = pTab->pSortCsr->iLastRowid; pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid; } pCsr->ePlan = FTS5_PLAN_SOURCE; pCsr->pExpr = pTab->pSortCsr->pExpr; rc = fts5CursorFirst(pTab, pCsr, bDesc); }else if( pCsr->pExpr ){ rc = fts5CursorParseRank(pConfig, pCsr, pRank); if( rc==SQLITE_OK ){ if( bOrderByRank ){ pCsr->ePlan = FTS5_PLAN_SORTED_MATCH; rc = fts5CursorFirstSorted(pTab, pCsr, bDesc); }else{ pCsr->ePlan = FTS5_PLAN_MATCH; rc = fts5CursorFirst(pTab, pCsr, bDesc); } } }else if( pConfig->zContent==0 ){ *pConfig->pzErrmsg = sqlite3_mprintf( "%s: table does not support scanning", pConfig->zName ); rc = SQLITE_ERROR; }else{ /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup ** by rowid (ePlan==FTS5_PLAN_ROWID). */ pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN); rc = sqlite3Fts5StorageStmt( pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg ); if( rc==SQLITE_OK ){ if( pCsr->ePlan==FTS5_PLAN_ROWID ){ sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq); }else{ sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid); sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid); } rc = fts5NextMethod(pCursor); } } filter_out: sqlite3Fts5ExprFree(pExpr); pConfig->pzErrmsg = pzErrmsg; return rc; } /* ** This is the xEof method of the virtual table. SQLite calls this ** routine to find out if it has reached the end of a result set. |
︙ | ︙ | |||
2228 2229 2230 2231 2232 2233 2234 | i64 iCsrId; assert( argc>=1 ); pAux = (Fts5Auxiliary*)sqlite3_user_data(context); iCsrId = sqlite3_value_int64(argv[0]); pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId); | | | 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 | i64 iCsrId; assert( argc>=1 ); pAux = (Fts5Auxiliary*)sqlite3_user_data(context); iCsrId = sqlite3_value_int64(argv[0]); pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId); if( pCsr==0 || pCsr->ePlan==0 ){ char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId); sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); }else{ fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]); } } |
︙ | ︙ |
Changes to ext/fts5/fts5_storage.c.
︙ | ︙ | |||
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | } if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ int f = SQLITE_PREPARE_PERSISTENT; if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB; rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0); sqlite3_free(zSql); if( rc!=SQLITE_OK && pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db)); } } } | > > | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | } if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ int f = SQLITE_PREPARE_PERSISTENT; if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB; p->pConfig->bLock++; rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0); p->pConfig->bLock--; sqlite3_free(zSql); if( rc!=SQLITE_OK && pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db)); } } } |
︙ | ︙ |
Changes to ext/fts5/test/fts5content.test.
︙ | ︙ | |||
249 250 251 252 253 254 255 | SELECT name FROM sqlite_master; } {xx xx_data xx_idx xx_docsize xx_config} do_execsql_test 6.2 { DROP TABLE xx; SELECT name FROM sqlite_master; } {} | > > | > > > > > > > > > > > > > | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | SELECT name FROM sqlite_master; } {xx xx_data xx_idx xx_docsize xx_config} do_execsql_test 6.2 { DROP TABLE xx; SELECT name FROM sqlite_master; } {} #--------------------------------------------------------------------------- # Check that an fts5 table cannot be its own content table. # reset_db do_execsql_test 7.1 { CREATE VIRTUAL TABLE t1 USING fts5(a, c=t1 ); INSERT INTO t1( a ) VALUES('abc'); } do_catchsql_test 7.2 { SELECT * FROM t1; } {1 {recursively defined fts5 content table}} do_catchsql_test 7.3 { SELECT * FROM t1('abc'); } {1 {recursively defined fts5 content table}} finish_test |
Changes to ext/fts5/test/fts5corrupt3.test.
︙ | ︙ | |||
763 764 765 766 767 768 769 | | 4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 heck....optimize | end c13.db SELECT * FROM t1 WHERE t1 MATCH 'abandon'; }]} {} do_catchsql_test 13.1 { SELECT * FROM t1 WHERE t1 MATCH 'abandon'; | | | 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 | | 4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 heck....optimize | end c13.db SELECT * FROM t1 WHERE t1 MATCH 'abandon'; }]} {} do_catchsql_test 13.1 { SELECT * FROM t1 WHERE t1 MATCH 'abandon'; } {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db do_test 14.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 28672 pagesize 4096 filename c14b.db |
︙ | ︙ | |||
954 955 956 957 958 959 960 | | 48: 01 00 00 10 10 04 02 02 00 00 00 00 00 00 00 00 ................ | 64: 70 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00 p...........p... | end c16.db }]} {} do_catchsql_test 15.1 { INSERT INTO t1(t1) VALUES('integrity-check'); | | | 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 | | 48: 01 00 00 10 10 04 02 02 00 00 00 00 00 00 00 00 ................ | 64: 70 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00 p...........p... | end c16.db }]} {} do_catchsql_test 15.1 { INSERT INTO t1(t1) VALUES('integrity-check'); } {/*malformed database schema*/} #--------------------------------------------------------------------------- # reset_db do_test 16.0 { sqlite3 db {} db deserialize [decode_hexdb { |
︙ | ︙ | |||
3899 3900 3901 3902 3903 3904 3905 | | 448: 54 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 TUAL TABLE t1 US | 464: 49 4e 47 20 66 74 73 35 28 61 2c 62 2c 63 29 00 ING fts5(a,b,c). | 480: 00 00 39 00 00 00 00 00 00 00 00 00 00 00 00 00 ..9............. | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end crash-fed6e90021ba5d.db }]} {} | | | | | | 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 | | 448: 54 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 TUAL TABLE t1 US | 464: 49 4e 47 20 66 74 73 35 28 61 2c 62 2c 63 29 00 ING fts5(a,b,c). | 480: 00 00 39 00 00 00 00 00 00 00 00 00 00 00 00 00 ..9............. | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end crash-fed6e90021ba5d.db }]} {} do_catchsql_test 33.1 { CREATE VIRTUAL TABLE t2 USING fts5vocab('t1','row'); CREATE VIRTUAL TABLE t3 USING fts5vocab('t1','col'); CREATE VIRTUAL TABLE t4 USING fts5vocab('t1','instance'); } {/*malformed database schema*/} do_catchsql_test 33.2 { SELECT * FROM t2; } {/*malformed database schema*/} do_catchsql_test 33.3 { SELECT * FROM t2, t3, t4 WHERE t2.term=t3.term AND t3.term=t4.term; } {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db do_test 34.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 40960 pagesize 4096 filename crash-a60a9da4c8932f.db |
︙ | ︙ | |||
4633 4634 4635 4636 4637 4638 4639 | | 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end null-memcmp-param-1..db }]} {} do_catchsql_test 37.1 { SELECT * FROM t3; | | | | | 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 | | 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end null-memcmp-param-1..db }]} {} do_catchsql_test 37.1 { SELECT * FROM t3; } {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db do_execsql_test 37a.0 { CREATE VIRTUAL TABLE t1 USING fts5(b, c); INSERT INTO t1 VALUES('a', 'b'); SELECT quote(block) FROM t1_data WHERE rowid=10; } {X'000000000101010001010101'} do_execsql_test 37a.1 { UPDATE t1_data SET block = X'FFFFFFFF0101010001010101' WHERE rowid = 10; SELECT rowid FROM t1('a'); } {1} #------------------------------------------------------------------------- reset_db do_execsql_test 38.0 { |
︙ | ︙ | |||
4890 4891 4892 4893 4894 4895 4896 | | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 uild....optimize | end crash-fd2a1313e5b5e9.db }]} {} do_catchsql_test 38.1 { UPDATE t1 SET b=quote(zeroblob(200)) WHERE t1 MATCH 'thread*'; | | | 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 | | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 uild....optimize | end crash-fd2a1313e5b5e9.db }]} {} do_catchsql_test 38.1 { UPDATE t1 SET b=quote(zeroblob(200)) WHERE t1 MATCH 'thread*'; } {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db do_test 39.0 { sqlite3 db {} db deserialize [decode_hexdb { .open --hexdb |
︙ | ︙ | |||
5322 5323 5324 5325 5326 5327 5328 | | 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version. | page 6 offset 20480 | 0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00 ................ | 4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09 ................ | end crash2.txt.db }]} {} | | | | | 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 | | 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version. | page 6 offset 20480 | 0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00 ................ | 4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09 ................ | end crash2.txt.db }]} {} do_catchsql_test 40.1 { BEGIN; INSERT INTO t1(b) VALUES(X'819192e578de3fa24af3733ca8769291a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bf'); INSERT INTO t1(b) VALUES(X'c8ae0d0e7c3175946e62ba2b449511d4eb504079984a20f77969f62206c9f3d7ea25358ab705e6978627290b6d48db9032f815a06a79a4f4b809841a0942eed12954ed166f666111812a508abc3bec87958846edaec0a6fe14564bc0a4b78f1c35ebcacca6bae29cc37ae9b59d8a2d7593af1e47dda0ece2268a98d20febafad037964f139851f9a57f48b3706b01721769071991412044cd6006f1d72eb6eb4aa5ad77e378176db8c15575fbeee47165e38a7c6c5a557ac2dfe11813976eaf6741cf593a9e457053a3c34cddfbe605a6e25419f993de8374fafcd3636509d8416a51dc7bcc14cfca322ae343078f47e23522431c17d0da0c033'); INSERT INTO t1(b) VALUES(X'dc29a94e873a45a4243fce9b912aaefbadf1d0423e0345793874b356eeb500b92fb05284c1601fe9bad3143f72162f10242cec27c44ebf764c8fc9fb0824e32c4161472a4f914f579e0e8274f08ca1a02e59b9d8eec1f31061f9ccb9ed97a6f06534e991f7992c761489e6a7724f6e9c2b581e77487ded3a986d53c4419bbd3e9747cee300e670dd7294874c77e2ed48da68eaa6c3ec954a09ac410493d98e34d6686e54fbbe80696705f10e040c66093efb40746b33600685c94c664c7942835a9e954866121d5dcfb2cb12e92521ea3df175ee17072502dad9b9c1565f801b2179799011eb7418bfa00323e3157589e648ff7378be233c79b7'); } {/*malformed database schema*/} do_catchsql_test 40.2 { INSERT INTO t1(a,b) VALUES(1,11),(2,22),(3, true ),(4,44); } {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db do_execsql_test 41.0 { CREATE VIRTUAL TABLE t1 USING fts5(a,b,c); REPLACE INTO t1_data VALUES(1,X'255a5824'); REPLACE INTO t1_data VALUES(10,X'0a1000000102020002010101020101'); |
︙ | ︙ | |||
5785 5786 5787 5788 5789 5790 5791 | | 0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00 ................ | 4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09 ................ | end 89028ffd2c29b679e250.db }]} {} do_catchsql_test 43.1 { INSERT INTO t1(t1) VALUES('optimize'); | | | 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 | | 0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00 ................ | 4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09 ................ | end 89028ffd2c29b679e250.db }]} {} do_catchsql_test 43.1 { INSERT INTO t1(t1) VALUES('optimize'); } {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db do_execsql_test 44.1 { CREATE VIRTUAL TABLE t1 USING fts5(a,b unindexed,c,tokenize="porter ascii"); REPLACE INTO t1_data VALUES(1,X'03090009'); REPLACE INTO t1_data VALUES(10,X'000000000103030003010101020101030101'); |
︙ | ︙ | |||
6043 6044 6045 6046 6047 6048 6049 | INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); | | | 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 | INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); } {/*malformed database schema*/} #-------------------------------------------------------------------------- reset_db do_test 46.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 32768 pagesize 4096 filename crash-1ee8bd451dd1ad.db |
︙ | ︙ | |||
6261 6262 6263 6264 6265 6266 6267 | | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 uild....optimize | end crash-1ee8bd451dd1ad.db }]} {} do_catchsql_test 46.1 { SELECT snippet(t1,'[','', '--',-1,10) FROM t1('*'); | | | 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 | | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 uild....optimize | end crash-1ee8bd451dd1ad.db }]} {} do_catchsql_test 46.1 { SELECT snippet(t1,'[','', '--',-1,10) FROM t1('*'); } {/*malformed database schema*/} #-------------------------------------------------------------------------- reset_db do_test 47.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 40960 pagesize 4096 filename 4b6fc659283f2735616c.db |
︙ | ︙ | |||
6414 6415 6416 6417 6418 6419 6420 | | 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end 4b6fc659283f2735616c.db }]} {} do_catchsql_test 47.1 { INSERT INTO t1(t1) VALUES('integrity-check'); | | | | 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 | | 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end 4b6fc659283f2735616c.db }]} {} do_catchsql_test 47.1 { INSERT INTO t1(t1) VALUES('integrity-check'); } {/*malformed database schema*/} do_catchsql_test 47.2 { SELECT count(*) FROM ( SELECT snippet(t1, -1, '.', '..', '[', 50), highlight(t1, 2, '[', ']') FROM t1('g h') WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank ) } {/*malformed database schema*/} #-------------------------------------------------------------------------- reset_db do_test 48.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 32768 pagesize 4096 filename crash-44a8305b4bd86f.db |
︙ | ︙ | |||
6904 6905 6906 6907 6908 6909 6910 | do_catchsql_test 50.1 { SELECT term FROM t4 WHERE term LIKE '»as'; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db | | | 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 | do_catchsql_test 50.1 { SELECT term FROM t4 WHERE term LIKE '»as'; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_execsql_test 51.0 { BEGIN TRANSACTION; PRAGMA writable_schema=ON; CREATE VIRTUAL TABLE t1 USING fts5(a,b,c); CREATE TABLE IF NOT EXISTS 't1_data'(id INTEGER PRIMARY KEY, block BLOB); REPLACE INTO t1_data VALUES(1,X'2eb1182424'); REPLACE INTO t1_data VALUES(10,X'000000000102080002010101020107'); INSERT INTO t1_data VALUES(137438953473,X'0000032b0230300102060102060102061f0203010203010203010832303136303630390102070102070102070101340102050102050102050101350102040102040102040207303030303030301c023d010204010204010662696e6172790306010202030601020203060102020306010202030601020203060102020306010202030601020203060102020306010202030601020203060102020108636f6d70696c657201020201020201020201066462737461740702030102030102030204656275670402020102020102020107656e61626c6507020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020202087874656e73696f6e1f02040102040102040104667473340a02030102030102030401350d020301020301020301036763630102030102030102030206656f706f6c7910020301020301020301056a736f6e3113020301020301020301046c6f61641f020301020301020301036d61781c02020102020102020205656d6f72791c020301020301020304047379733516020301020301020301066e6f6361736502060102020306010202030601020213060102020306010202030601020203060102020306010202030601020203060102020306010202030601020201046f6d69741f0202010202010202010572747265651902030102030102030402696d010601020203060102020306010202030601020203060102020306010202030601020203060102020306010202030601020203060102020306010202010a7468726561647361666522020201020201020201047674616207020401020401020401017801060101020106010102010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102ad060101020106010102010601010201060101020106010101010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102010601010201060101020415130c0c124413110f47130efc0e11100f0e100f440f1040150f'); |
︙ | ︙ | |||
6972 6973 6974 6975 6976 6977 6978 | INSERT INTO t2 VALUES('integrity-check'); PRAGMA writable_schema=OFF; COMMIT; } {} do_catchsql_test 51.1 { SELECT max(rowid)==0 FROM t1('e*'); | | | 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 | INSERT INTO t2 VALUES('integrity-check'); PRAGMA writable_schema=OFF; COMMIT; } {} do_catchsql_test 51.1 { SELECT max(rowid)==0 FROM t1('e*'); } {1 {database disk image is malformed}} #-------------------------------------------------------------------------- reset_db do_test 52.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 40960 pagesize 4096 filename crash-2b92f77ddfe191.db |
︙ | ︙ | |||
7126 7127 7128 7129 7130 7131 7132 | | 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end crash-2b92f77ddfe191.db }]} {} do_catchsql_test 52.1 { SELECT fts5_decode(id, block) FROM t1_data; | | | 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 | | 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end crash-2b92f77ddfe191.db }]} {} do_catchsql_test 52.1 { SELECT fts5_decode(id, block) FROM t1_data; } {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db do_test 53.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 24576 pagesize 4096 filename crash-dbe9b7614da103.db |
︙ | ︙ | |||
7342 7343 7344 7345 7346 7347 7348 | | 4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 0c e9 ................ | end crash-dbe9b7614da103.db }]} {} do_catchsql_test 53.1 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x<>1 FROM c WHERE x<10) INSERT INTO t1(a) SELECT randomblob(3000) FROM c; | | | 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 | | 4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 0c e9 ................ | end crash-dbe9b7614da103.db }]} {} do_catchsql_test 53.1 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x<>1 FROM c WHERE x<10) INSERT INTO t1(a) SELECT randomblob(3000) FROM c; } {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db do_test 54.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 24576 pagesize 4096 filename crash-03a1855566d9ae.db |
︙ | ︙ | |||
7558 7559 7560 7561 7562 7563 7564 | | 0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00 ................ | 4080: 00 00 23 03 02 01 03 03 02 02 01 02 02 00 f2 09 ..#............. | end crash-03a1855566d9ae.db }]} {} do_catchsql_test 54.1 { SELECT rowid==-1 FROM t1('t*'); | | | 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 | | 0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00 ................ | 4080: 00 00 23 03 02 01 03 03 02 02 01 02 02 00 f2 09 ..#............. | end crash-03a1855566d9ae.db }]} {} do_catchsql_test 54.1 { SELECT rowid==-1 FROM t1('t*'); } {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db do_test 55.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 32768 pagesize 4096 filename crash-b366b5ac0d3887.db |
︙ | ︙ | |||
7773 7774 7775 7776 7777 7778 7779 | | 0: 0d 00 00 00 03 0f d6 00 0f f4 0f e9 0f d6 00 00 ................ | 4048: 00 00 00 00 00 00 11 03 02 2b 69 6e 74 65 77 72 .........+intewr | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 uild....optimize | end crash-b366b5ac0d3887.db }]} {} | | | | 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 | | 0: 0d 00 00 00 03 0f d6 00 0f f4 0f e9 0f d6 00 00 ................ | 4048: 00 00 00 00 00 00 11 03 02 2b 69 6e 74 65 77 72 .........+intewr | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 uild....optimize | end crash-b366b5ac0d3887.db }]} {} do_catchsql_test 55.1 { SAVEPOINT one; DELETE FROM t1 WHERE a MATCH 'ts'; } {/*malformed database schema*/} do_execsql_test 55.2 { ROLLBACK TO one; } #------------------------------------------------------------------------- reset_db |
︙ | ︙ | |||
8009 8010 8011 8012 8013 8014 8015 | # may return SQLITE_CONSTRAINT instead of SQLITE_CORRUPT. This is because # the corrupt db in the test over-reads the page buffer slightly, with # different results depending on whether or not the page-cache is in use. if {$res=="1 {constraint failed}"} { set res "1 {database disk image is malformed}" } set res | | | 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 | # may return SQLITE_CONSTRAINT instead of SQLITE_CORRUPT. This is because # the corrupt db in the test over-reads the page buffer slightly, with # different results depending on whether or not the page-cache is in use. if {$res=="1 {constraint failed}"} { set res "1 {database disk image is malformed}" } set res } {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db do_test 57.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 28672 pagesize 4096 filename x.db |
︙ | ︙ | |||
8127 8128 8129 8130 8131 8132 8133 | | 4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63 d...+integrity-c | 4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 heck....optimize | end x.db }]} {} do_catchsql_test 57.1 { INSERT INTO t1(t1) VALUES('optimize') | | | 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 | | 4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63 d...+integrity-c | 4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 heck....optimize | end x.db }]} {} do_catchsql_test 57.1 { INSERT INTO t1(t1) VALUES('optimize') } {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db do_test 58.0 { sqlite3 db {} db deserialize [decode_hexdb { .open --hexdb |
︙ | ︙ | |||
8335 8336 8337 8338 8339 8340 8341 | | 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p | 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version. | page 6 offset 20480 | 4080: 00 00 23 03 02 01 03 03 02 00 00 00 00 00 00 00 ..#............. | end crash-5a5acd0ab42d31.db }]} {} | | | | 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 | | 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p | 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version. | page 6 offset 20480 | 4080: 00 00 23 03 02 01 03 03 02 00 00 00 00 00 00 00 ..#............. | end crash-5a5acd0ab42d31.db }]} {} do_catchsql_test 58.1 { SELECT * FROM t1('t*'); } {/*malformed database schema*/} #------------------------------------------------------------------------- do_test 59.0 { sqlite3 db {} db deserialize [decode_hexdb { .open --hexdb | size 32768 pagesize 4096 filename crash-96b136358d01ec.db |
︙ | ︙ | |||
8540 8541 8542 8543 8544 8545 8546 | | page 8 offset 28672 | 4048: 00 00 00 00 00 00 5d 03 02 2b 69 6e 74 00 00 00 ......]..+int... | end crash-96b136358d01ec.db }]} {} do_catchsql_test 59.1 { SELECT (matchinfo(591,t1)) FROM t1 WHERE t1 MATCH 'e*eŸ' | | | 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 | | page 8 offset 28672 | 4048: 00 00 00 00 00 00 5d 03 02 2b 69 6e 74 00 00 00 ......]..+int... | end crash-96b136358d01ec.db }]} {} do_catchsql_test 59.1 { SELECT (matchinfo(591,t1)) FROM t1 WHERE t1 MATCH 'e*eŸ' } {1 {database disk image is malformed}} #------------------------------------------------------------------------- do_test 60.0 { sqlite3 db {} db deserialize [decode_hexdb { .open --hexdb | size 32768 pagesize 4096 filename crash-c77b90b929dc92.db |
︙ | ︙ | |||
8746 8747 8748 8749 8750 8751 8752 | | 4048: 00 00 00 00 00 00 5d 03 00 00 00 00 00 00 00 00 ......]......... | end crash-c77b90b929dc92.db }]} {} do_catchsql_test 60.2 { SELECT (matchinfo(t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ' | | | 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 | | 4048: 00 00 00 00 00 00 5d 03 00 00 00 00 00 00 00 00 ......]......... | end crash-c77b90b929dc92.db }]} {} do_catchsql_test 60.2 { SELECT (matchinfo(t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ' } {1 {database disk image is malformed}} #------------------------------------------------------------------------- do_test 61.0 { sqlite3 db {} db deserialize [decode_hexdb { .open --hexdb | size 28672 pagesize 4096 filename crash-e5fa281edabddf.db |
︙ | ︙ | |||
8944 8945 8946 8947 8948 8949 8950 | | 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................ | page 7 offset 24576 | 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end crash-e5fa281edabddf.db }]} {} | | | | | 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 | | 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................ | page 7 offset 24576 | 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end crash-e5fa281edabddf.db }]} {} do_catchsql_test 61.1 { CREATE VIRTUAL TABLE t3 USING fts5vocab('t1'(),'col' ); } {/*malformed database schema*/} do_catchsql_test 61.2 { SELECT * FROM t3 ORDER BY rowid; } {/*malformed database schema*/} breakpoint #------------------------------------------------------------------------- do_test 62.0 { sqlite3 db {} db deserialize [decode_hexdb { .open --hexdb |
︙ | ︙ | |||
9155 9156 9157 9158 9159 9160 9161 | | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end crash-44942694542e1e.db }]} {} do_catchsql_test 62.1 { WITH c(x) AS (VALUES(false) UNION ALL SELECT x+1 FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 9507 9508 9509 9510 9511 9512 9513 9514 9515 9516 9517 9518 9519 9520 9521 9522 9523 9524 9525 9526 9527 9528 9529 9530 9531 9532 9533 9534 9535 9536 9537 9538 9539 9540 9541 9542 9543 9544 9545 9546 9547 9548 9549 9550 9551 9552 9553 9554 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565 9566 9567 9568 9569 9570 9571 9572 9573 9574 9575 9576 9577 9578 9579 9580 9581 9582 9583 9584 9585 9586 9587 9588 9589 9590 9591 9592 9593 9594 9595 9596 9597 9598 9599 9600 9601 9602 9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 9617 9618 9619 9620 9621 9622 9623 9624 9625 9626 9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 9642 9643 9644 9645 9646 9647 9648 9649 9650 9651 9652 9653 9654 9655 9656 9657 9658 9659 9660 9661 9662 9663 9664 9665 9666 9667 9668 9669 9670 9671 9672 9673 9674 9675 9676 9677 9678 9679 9680 9681 9682 9683 9684 9685 9686 9687 9688 9689 9690 9691 9692 9693 9694 9695 9696 9697 9698 9699 9700 | | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end crash-44942694542e1e.db }]} {} do_catchsql_test 62.1 { WITH c(x) AS (VALUES(false) UNION ALL SELECT x+1 FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; } {/*malformed database schema*/} #--------------------------------------------------------------------------- do_test 63.0 { sqlite3 db {} db deserialize [decode_hexdb { .open --hexdb | size 24576 pagesize 4096 filename crash-8230e6c3b368f5.db | page 1 offset 0 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ | 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S | 112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00 .....3.......... | 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................ | 3600: 06 06 17 11 11 01 31 74 61 62 7c 65 62 63 62 62 ......1tab|ebcbb | 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb | 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table | 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf | 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE | 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR | 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI | 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...! | 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs | 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR | 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 9d EATE TABLE 't1_. | 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG | 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, | 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i....... | 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i | 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE | 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid, | 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM | 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t | 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO | 3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c WIDU........tabl | 3936: 65 64 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 ed1_datat1_data. | 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1 | 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE | 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b | 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 10 11 lock BLOB)T..... | 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA | 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE | 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a | 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3 | 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..) | page 2 offset 4096 | 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L.... | 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........ | 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........ | 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........ | 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........ | 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 0a cc 0a ad ...~.H.......... | 96: 0a 8c 0a 6d 0a 4d 0a 2b 0a 0c 09 ec 09 ca 09 a8 ...m.M.+........ | 112: 09 86 09 63 0f f1 00 00 00 00 00 00 00 00 00 00 ...c............ | 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................ | 2384: 30 00 00 00 01 01 03 35 00 03 01 01 12 02 01 12 0......5........ | 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>... | 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh | 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............< | 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n | 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb............. | 2480: 00 3c 00 00 00 16 04 33 74 68 65 13 06 01 01 04 .<.....3the..... | 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe........... | 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num... | 2528: 01 05 01 03 75 61 62 03 02 03 04 0a 19 8c 80 80 ....uab......... | 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 ec 68 03 02 .....8.....2.h.. | 2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts......... | 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta.. | 2592: 03 02 01 68 03 06 01 01 04 04 17 1b 8c 80 80 80 ...h............ | 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu... | 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of.......... | 2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft. | 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is.......... | 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t.. | 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w......... | 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n... | 2720: 01 02 05 01 01 6f 03 06 01 01 06 04 09 18 8c 80 .....o.......... | 2736: 80 80 80 06 03 00 36 00 00 00 13 04 02 31 66 03 ......6......1f. | 2752: 02 02 01 01 69 03 06 01 01 03 05 06 1c 8c 80 80 ....i........... | 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the. | 2784: 06 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where..... | 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0....... | 2816: 06 30 74 61 62 6c 65 03 02 03 07 1c 8c 80 80 80 .0table......... | 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe | 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of...... | 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02 .......,........ | 2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03 0n.............. | 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux. | 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00 ....is........*. | 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$.......... | 2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80 ................ | 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row | 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther.... | 2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01 .........0...... | 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........ | 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row | 3040: 02 06 01 01 05 01 03 74 68 64 02 08 05 0a 1b 88 .......thd...... | 3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04 .......<........ | 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet.... | 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 03 32 .........<.....2 | 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and.. | 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<.... | 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro... | 3152: 01 43 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .C...........6.. | 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be.. | 3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 00 00 ............<... | 3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an. | 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8. | 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r.. | 3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00 ..............4. | 3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i.... | 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8... | 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a..... | 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<... | 3328: 16 06 30 74 68 65 72 65 02 02 01 00 02 30 21 02 ..0there.....0!. | 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0. | 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07 .......0the..... | 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>..... | 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows | 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 51 .............<.Q | 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between..... | 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............: | 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and....... | 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re.............. | 3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2 | 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................ | 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<.. | 3536: 00 16 05 34 74 51 62 6c 01 06 01 01 05 02 03 65 ...4tQbl.......e | 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............< | 3568: 00 00 00 16 05 34 65 17 63 68 01 02 03 01 04 70 .....4e.ch.....p | 3584: 72 65 73 01 02 05 04 09 1a 84 80 80 80 80 0f 03 res............. | 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter..... | 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he.............. | 3632: 03 00 3c 00 00 00 16 04 33 70 72 65 01 02 05 01 ..<.....3pre.... | 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............ | 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 03 ....:.....3for.. | 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts........... | 3696: 80 80 0c 03 00 3c 00 00 00 16 03 32 74 68 01 06 .....<.....2th.. | 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac....... | 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta | 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........ | 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01 ......8.....2in. | 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........ | 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo. | 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t........... | 3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t... | 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea....... | 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i. | 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p......... | 3888: 80 80 06 03 00 36 00 00 00 12 02 31 65 01 02 02 .....6.....1e... | 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f............. | 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term. | 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he.......... | 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 74 61 62 ............0tab | 3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03 le.............. | 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present | 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<.. | 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in | 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............: | 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 03 66 .....0each.....f | 4064: 6f 72 01 02 01 f4 09 06 01 03 00 12 03 0b 0f 00 or.............. | 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................ | page 3 offset 8192 | 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O......... | 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................ | 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._ | 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13 .V.M.A.8./.&.... | 64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd ................ | 80: 0e c3 0e ba 0e b0 0e a8 0e 9f 0e 00 00 00 00 00 ................ | 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................ | 3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4. | 3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th....... | 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w..... | 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n... | 3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 07 ....2.......1t.. | 3744: f4 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1. | 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th....... | 3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu.... | 3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n........... | 3808: 10 01 02 34 73 22 07 04 01 0e 01 02 34 20 08 04 ...4s.......4 .. | 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar | 3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t....... | 3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar.... | 3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08 ...1t.......1n.. | 3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12 | 3904: 0e 0b 04 01 16 01 02 30 74 00 00 00 00 00 00 00 .......0t....... | page 4 offset 12288 | 4064: 00 00 00 00 00 00 00 00 00 00 00 05 02 03 00 10 ................ | 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................ | page 5 offset 16384 | 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................ | 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p | 4080: 67 73 7a 08 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version. | end crash-8230e6c3b368f5.db }]} {} do_catchsql_test 63.1 { SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*'; } {/*malformed database schema*/} do_catchsql_test 63.2 { INSERT INTO t1(t1) VALUES('optimize'); } {/*malformed database schema*/} do_catchsql_test 63.3 { SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*'; } {/*malformed database schema*/} #--------------------------------------------------------------------------- do_test 64.0 { sqlite3 db {} db deserialize [decode_hexdb { .open --hexdb | size 28672 pagesize 4096 filename crash-4470f0b94422f7.db | page 1 offset 0 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06 .....@ ........ | 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04 ................ | 96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a ...............j | 112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 01 00 00 .....=.......... | 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..Y...!!..tablet | 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6e tt_configttt_con | 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45 fig.CREATE TABLE | 3600: 20 27 74 74 74 5f 63 6f 6e 66 69 67 27 28 6b 20 'ttt_config'(k | 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 PRIMARY KEY, v) | 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07 WITHOUT ROWID^.. | 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 64 .##...tablettt_d | 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a ocsizettt_docsiz | 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.CREATE TABLE ' | 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 ttt_docsize'(id | 3712: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY | 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07 KEY, sz BLOB)].. | 3744: 17 23 23 01 81 01 74 61 62 6c 65 74 74 74 5f 63 .##...tablettt_c | 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e ontentttt_conten | 3776: 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 t.CREATE TABLE ' | 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 ttt_content'(id | 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY | 3824: 4b 45 59 2c 20 63 30 2c 20 63 31 29 6c 03 07 17 KEY, c0, c1)l... | 3840: 1b 1b 01 81 2f 74 61 62 6c 65 74 74 74 5f 69 64 ..../tablettt_id | 3856: 78 74 74 74 5f 69 64 78 03 43 52 45 41 54 45 20 xttt_idx.CREATE | 3872: 54 41 42 4c 45 20 27 74 74 74 5f 69 64 78 27 28 TABLE 'ttt_idx'( | 3888: 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 6e segid, term, pgn | 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 73 o, PRIMARY KEY(s | 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 egid, term)) WIT | 3936: 48 4f 55 54 20 52 4f 57 49 44 58 02 07 17 1d 1d HOUT ROWIDX..... | 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 ...tablettt_data | 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 20 ttt_data.CREATE | 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 TABLE 'ttt_data' | 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM | 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARY KEY, block B | 4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c LOB):......_tabl | 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettttttCREATE VI | 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 RTUAL TABLE ttt | 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 USING fts5(a, b) | page 2 offset 4096 | 0: 0d 0f 44 00 05 0e 81 00 0f 1a 0e 81 0f af 0f 58 ..D............X | 16: 0e 98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 3712: 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01 .....0.......... | 3728: 01 01 02 01 01 03 01 01 81 24 8c 80 80 80 80 01 .........$...... | 3744: 04 00 82 4c 00 00 00 9b 02 30 65 03 1a 02 05 05 ...L.....0e..... | 3760: 07 05 01 01 04 03 03 08 03 03 01 2e 02 05 05 07 ................ | 3776: 05 07 05 07 05 01 01 04 03 03 08 03 03 08 03 03 ................ | 3792: 07 f3 03 02 01 65 03 1e 03 05 05 04 05 05 01 00 .....e.......... | 3808: 03 06 04 04 06 04 03 01 36 03 05 05 04 06 05 04 ........6....... | 3824: 06 05 04 05 05 01 01 03 06 04 04 06 04 04 06 04 ................ | 3840: 04 06 04 03 03 01 65 03 14 04 05 06 f5 05 01 01 ......e......... | 3856: 02 08 09 01 20 04 05 07 05 07 05 07 05 05 01 00 .... ........... | 3872: 02 08 0a 0a 0a 04 01 65 03 02 0a 01 06 0a 0a 0a .......e........ | 3888: 05 01 65 03 06 01 01 0a 01 0a 01 01 0a 0a 0a 04 ..e............. | 3904: 2b 31 21 0b 0f ef 00 14 2a 00 00 00 00 01 02 02 +1!.....*....... | 3920: 00 02 01 01 01 02 01 01 50 88 80 80 80 80 01 04 ........P....... | 3936: 00 81 24 00 00 00 47 02 30 65 02 1a 02 05 05 07 ..$...G.0e...... | 3952: 05 01 01 04 03 03 08 03 03 02 01 65 02 1e 03 05 ...........e.... | 3968: 05 04 05 05 01 01 03 06 04 04 06 04 03 03 01 65 ...............e | 3984: 02 14 04 05 07 05 05 01 01 02 08 0a 04 01 65 02 ..............e. | 4000: 02 0a 05 01 65 02 06 01 01 0a 04 12 14 0f 06 31 ....e..........1 | 4016: 84 80 80 80 80 01 03 00 68 00 00 00 2b 02 30 65 ........h...+.0e | 4032: 01 10 02 05 05 01 01 04 03 03 02 01 65 01 12 03 ............e... | 4048: 05 05 01 01 03 06 04 03 03 01 65 01 0e 04 05 05 ..........e..... | 4064: 01 01 02 08 04 0d 0e 06 01 03 00 12 04 4c 4c 00 .............LL. | 4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ | page 3 offset 8192 | 0: 0a 00 00 00 03 0f ec 00 0f 00 00 00 00 00 00 00 ................ | 4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c ................ | 4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02 ................ | page 4 offset 12288 | 0: 0d 00 00 00 04 0e 1a 00 0f c7 0f 5b 0e ef 0e 1a ...........[.... | 3600: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 00 81 ...........R.... | 3616: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65 ].Ue ee eee e ee | 3632: 20 65 65 65 20 65 20 65 65 20 65 65 65 66 20 65 eee e ee eeef e | 3648: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e | 3664: 20 65 65 20 65 65 65 65 20 65 65 20 65 65 65 20 ee eeee ee eee | 3680: 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 e ee eee e ee ee | 3696: 65 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 ee ee eee e ee e | 3712: 65 65 20 65 20 65 65 20 65 65 65 65 65 65 20 65 ee e ee eeeeee e | 3728: 65 20 65 20 65 20 65 20 65 65 20 65 65 65 20 65 e e e e ee eee e | 3744: 65 20 65 65 65 65 65 20 65 65 20 65 20 65 1f 65 e eeeee ee e e.e | 3760: 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65 65 ee eee ee eeeee | 3776: 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 65 ee e e e ee eee | 3792: 20 65 65 20 65 65 65 65 65 20 65 65 20 65 20 65 ee eeeee ee e e | 3808: 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 6a e ee eee ee eej | 3824: 03 03 ff 75 71 65 20 65 65 1f 65 65 65 20 65 20 ...uqe ee.eee e | 3840: 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 65 ee eee e ee eeee | 3856: 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 ee eee e ee eee | 3872: 20 65 20 65 65 20 65 65 65 65 65 65 20 65 65 20 e ee eeeeee ee | 3888: 65 20 65 20 65 20 65 65 20 65 65 65 20 65 65 20 e e e ee eee ee | 3904: 65 65 65 65 65 20 65 65 20 65 20 65 20 65 20 65 eeeee ee e e e e | 3920: 65 20 65 65 65 20 65 65 20 65 65 6a 02 04 00 75 e eee ee eej...u | 3936: 40 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 @e ee eee e ee e | 3952: 65 65 20 65 20 65 65 20 65 65 65 65 20 65 65 20 ee e ee eeee ee | 3968: 65 65 65 20 65 20 65 65 20 65 65 65 20 65 20 65 eee e ee eee e e | 3984: 65 20 65 65 65 65 65 65 20 65 65 20 65 20 65 20 e eeeeee ee e e | 4000: 65 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65 e ee eee ee eeee | 4016: 65 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 e ee e e e ee ee | 4032: 65 20 65 65 20 65 65 37 01 04 00 41 3f 65 20 65 e ee ee7...A?e e | 4048: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e | 4064: 20 65 65 20 65 65 65 65 65 65 20 65 65 20 65 20 ee eeeeee ee e | 4080: 65 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 e e ee eee ee ee | page 5 offset 16384 | 0: 0d 00 00 00 04 0f e4 00 0f f9 0f f2 0f eb 0f e4 ................ | 4064: 00 00 00 00 05 04 03 00 10 21 21 05 03 03 00 10 .........!!..... | 4080: 11 11 05 02 03 00 10 11 11 05 01 03 00 10 09 09 ................ | page 6 offset 20480 | 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end crash-4470f0b94422f7.db }]} {} do_catchsql_test 64.1 { SELECT * FROM ttt('e*'); } {1 {database disk image is malformed}} #--------------------------------------------------------------------------- do_test 65.0 { sqlite3 db {} db deserialize [decode_hexdb { .open --hexdb | size 28672 pagesize 4096 filename crash-3aef66940ace0c.db | page 1 offset 0 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ | 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6 | 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............ | 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet | 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE | 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta | 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c | 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB | 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k | 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v) | 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[. | 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d | 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize | 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't | 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN | 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE | 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...! | 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont | 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR | 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c | 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG | 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, | 3776: 63 30 2c 20 63 31 2c d6 63 32 29 69 04 07 17 19 c0, c1,.c2)i.... | 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt | 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB | 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi | 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P | 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid | 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT | 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t | 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da | 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE | 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT | 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY | 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8.. | 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR | 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB | 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5 | 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... | page 3 offset 8192 | 0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00 ................ | 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J.......... | 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00......... | 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 31 31 36 30 ...........21160 | 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1 609...........3. | 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 01 02 ..........5..... | 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d ......0000000..= | 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary.. | 3328: 01 02 02 03 06 01 01 f2 03 06 4e 02 02 03 06 01 ..........N..... | 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ | 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ | 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp | 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d | 3408: 62 73 74 61 74 07 02 03 01 02 13 01 02 03 02 04 bstat........... | 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65 ebug...........e | 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable........... | 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................ | 3472: 01 02 02 01 02 01 f1 02 02 01 02 02 01 02 02 01 ................ | 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................ | 3504: 02 01 02 02 02 08 76 b4 65 6e 73 69 6f 6e 1f 02 ......v.ension.. | 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4... | 3536: 01 02 03 01 02 03 04 01 25 0d 02 03 01 02 03 01 ........%....... | 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc......... | 3568: 02 06 65 6f 70 6f 6c 79 0f f2 03 01 02 03 01 02 ..eopoly........ | 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........ | 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load......... | 3616: 00 03 6d 61 78 1c 02 0c 01 02 02 01 02 02 02 05 ..max........... | 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory........... | 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n | 3664: 6f 63 61 73 65 02 06 01 02 02 13 06 00 f2 02 03 ocase........... | 3680: 06 01 12 02 13 06 01 02 02 03 06 01 02 02 03 06 ................ | 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ | 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ | 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit......... | 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree......... | 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............ | 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ | 3792: 02 02 03 06 01 02 02 03 06 01 02 02 8e 06 01 02 ................ | 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ | 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe.... | 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab..... | 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x......... | 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................ | 3888: 01 06 01 11 02 01 06 01 01 02 01 06 01 01 02 01 ................ | 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ | 3920: 01 01 02 01 06 01 01 01 01 06 01 01 02 01 06 01 ................ | 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ | 3952: 02 01 06 01 01 01 f1 06 01 01 02 ad 06 01 01 02 ................ | 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ | 3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06 ................ | 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ | 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ | 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................ | 4048: 12 44 13 11 0f 47 13 0e fc 0e 11 10 0f 0e 10 0f .D...G.......... | 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$. | 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ | page 4 offset 12288 | 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................ | page 5 offset 16384 | 0: 0d 00 00 00 24 0c 0a 00 00 00 00 00 00 00 00 00 ....$........... | 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%. | 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI | 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA | 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f DSAFE=0XNOCASE.. | 3136: 05 00 25 0f 17 54 48 52 45 41 44 43 41 46 45 3d ..%..THREADCAFE= | 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM | 3168: 49 54 20 4b 4f 41 44 21 45 58 54 45 4e 53 49 4f IT KOAD!EXTENSIO | 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O | 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI | 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. | 3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMYT LOAD EXTENS | 3248: 49 4f 4e 58 52 54 56 a9 4d 1f 1e 05 00 33 0f 19 IONXRTV.M....3.. | 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000 | 3280: 30 30 30 57 42 49 4e 31 52 59 1f 1d 05 00 33 0f 000WBIN1RY....3. | 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 | 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 32 0000XNOCASE....2 | 3328: 0f 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30 ..NAX MEMORY-500 | 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% | 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB | 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB | 3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17 LE RTREEYNOCASE. | 3408: 19 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 .f.%..ENABLE RTR | 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E | 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI | 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL | 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE | 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME | 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 10 25 MSYS5XRTRIM....% | 3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN@BLE JSON1XB | 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB | 3552: 4c 45 20 4a 53 4f 4e 32 58 4e 4f 43 41 53 45 17 LE JSON2XNOCASE. | 3568: 13 05 00 25 0f 17 45 4d 41 42 4c 45 20 4a 53 4f ...%..EMABLE JSO | 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E | 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI | 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4f 81 42 4c NARY....)..EO.BL | 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45 E GEOPOLYXNOCQSE | 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE | 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....# | 3680: 0f 1a 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI | 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL | 3712: 45 20 46 54 53 35 48 4e 4f 43 41 53 45 16 1d 05 E FTS5HNOCASE... | 3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X | 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB | 3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b LE FUS4XBINARY.. | 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 | 3792: 57 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e WNOCASE....#..EN | 3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e ABLE FTS4.RTRIM. | 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS | 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. | 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS | 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE. | 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS | 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM.. | 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 8a 4e 41 52 .....DEBUGXB.NAR | 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO | 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG | 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM | 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 | 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY' | 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3f 87 ...C..COMPILER?. | 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060 | 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C | 4064: 45 0d 60 59 4c 45 52 3d 67 63 63 2d 35 2e 34 2d E.`YLER=gcc-5.4- | 4080: 30 20 32 30 31 36 30 36 30 39 00 00 00 00 00 00 0 20160609...... | page 6 offset 20480 | 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#...... | 3824: 06 22 03 01 12 02 01 01 06 21 03 00 12 03 01 01 .........!...... | 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 02 01 . .............. | 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................ | 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................ | 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................ | 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................ | 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................ | 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................ | 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................ | 3968: 06 00 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................ | 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................ | 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................ | 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................ | 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................ | 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................ | 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................ | 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................ | page 7 offset 24576 | 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. | end crash-3aef66940ace0c.db }]} {} do_catchsql_test 65.1 { SELECT ( MATCH (t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ' } {1 {database disk image is malformed}} sqlite3_fts5_may_be_corrupt 0 finish_test |
Changes to ext/fts5/test/fts5faultB.test.
︙ | ︙ | |||
142 143 144 145 146 147 148 149 150 151 | 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 | > > > > > > > > > > > > > > > > > > > > > > | 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 | 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}} } #------------------------------------------------------------------------- # Test OOM injection in a query with two MATCH expressions # reset_db do_execsql_test 6.0 { CREATE VIRTUAL TABLE t1 USING fts5(a); INSERT INTO t1 VALUES('a b c d'); -- 1 INSERT INTO t1 VALUES('d a b c'); -- 2 INSERT INTO t1 VALUES('c d a b'); -- 3 INSERT INTO t1 VALUES('b c d a'); -- 4 } do_faultsim_test 6.1 -faults oom* -body { execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a' AND t1 MATCH 'b' } } -test { faultsim_test_result {0 {1 2 3 4}} } do_faultsim_test 6.2 -faults oom* -body { execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a OR b' AND t1 MATCH 'c OR d' } } -test { faultsim_test_result {0 {1 2 3 4}} } finish_test |
Added ext/fts5/test/fts5misc.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | # 2019 September 02 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the FTS5 module. # source [file join [file dirname [info script]] fts5_common.tcl] set testprefix fts5misc # If SQLITE_ENABLE_FTS5 is not defined, omit this file. ifcapable !fts5 { finish_test return } do_execsql_test 1.0 { CREATE VIRTUAL TABLE t1 USING fts5(a); } do_catchsql_test 1.1.1 { SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*'); } {1 {unknown special query: }} do_catchsql_test 1.1.2 { SELECT a FROM t1 WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*')); } {1 {unknown special query: }} do_catchsql_test 1.2.1 { SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*id'); } {0 {{}}} do_catchsql_test 1.2.2 { SELECT a FROM t1 WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*id')); } {0 {}} do_catchsql_test 1.3.1 { SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads'); } {1 {no such cursor: 1}} do_catchsql_test 1.3.2 { SELECT a FROM t1 WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads')); } {1 {no such cursor: 1}} db close sqlite3 db test.db do_catchsql_test 1.3.3 { SELECT a FROM t1 WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads')); } {1 {no such cursor: 1}} finish_test |
Added ext/fts5/test/fts5multi.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | # 2014 September 13 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the FTS5 module. # source [file join [file dirname [info script]] fts5_common.tcl] set testprefix fts5multi # If SQLITE_ENABLE_FTS5 is not defined, omit this file. ifcapable !fts5 { finish_test return } fts5_aux_test_functions db do_execsql_test 1.0 { CREATE VIRTUAL TABLE t1 USING fts5(a, b, c); INSERT INTO t1 VALUES('gg bb bb' ,'gg ff gg' ,'ii ii'); INSERT INTO t1 VALUES('dd dd hh kk','jj' ,'aa'); INSERT INTO t1 VALUES('kk gg ee' ,'hh cc' ,'hh jj aa cc'); INSERT INTO t1 VALUES('hh' ,'bb jj cc' ,'kk ii'); INSERT INTO t1 VALUES('kk dd kk ii','aa ee aa' ,'ee'); INSERT INTO t1 VALUES('ee' ,'ff gg kk aa','ee ff ee'); INSERT INTO t1 VALUES('ff jj' ,'gg ee' ,'kk ee gg kk'); INSERT INTO t1 VALUES('ff ee dd hh','kk ee' ,'gg dd'); INSERT INTO t1 VALUES('bb' ,'aa' ,'bb aa'); INSERT INTO t1 VALUES('hh cc bb' ,'ff bb' ,'cc'); INSERT INTO t1 VALUES('jj' ,'ff dd bb aa','dd dd ff ff'); INSERT INTO t1 VALUES('ff dd gg dd','gg aa bb ff','cc'); INSERT INTO t1 VALUES('ff aa cc jj','kk' ,'ii dd'); INSERT INTO t1 VALUES('jj dd' ,'cc' ,'ii hh ee aa'); INSERT INTO t1 VALUES('ff ii hh' ,'dd' ,'gg'); INSERT INTO t1 VALUES('ff dd gg hh','hh' ,'ff dd'); INSERT INTO t1 VALUES('cc cc' ,'ff dd ff' ,'bb'); INSERT INTO t1 VALUES('ii' ,'bb ii' ,'jj kk'); INSERT INTO t1 VALUES('ff hh' ,'hh bb' ,'bb dd ee'); INSERT INTO t1 VALUES('jj kk' ,'jj' ,'gg ff cc'); INSERT INTO t1 VALUES('dd kk' ,'ii gg' ,'dd'); INSERT INTO t1 VALUES('cc' ,'aa ff' ,'ii'); INSERT INTO t1 VALUES('bb ff bb ii','bb kk bb aa','hh ff ii dd'); INSERT INTO t1 VALUES('aa' ,'ee bb jj jj','dd'); INSERT INTO t1 VALUES('kk dd cc' ,'aa jj' ,'ee aa ff'); INSERT INTO t1 VALUES('aa gg aa' ,'jj' ,'ii kk hh gg'); INSERT INTO t1 VALUES('ff hh aa' ,'jj ii' ,'hh dd bb jj'); INSERT INTO t1 VALUES('hh' ,'aa gg kk' ,'bb ee'); INSERT INTO t1 VALUES('bb' ,'ee' ,'gg'); INSERT INTO t1 VALUES('dd kk' ,'kk bb aa' ,'ee'); } foreach {tn c1 e1 c2 e2} { 1 t1 aa t1 bb 2 a aa b bb 3 a "aa OR bb OR cc" b "jj OR ii OR hh" 4 t1 "aa AND bb" t1 "cc" 5 c "kk" b "aa OR bb OR cc OR dd OR ee" } { if {$c1=="t1"} { set lhs "( $e1 )" } else { set lhs "$c1 : ( $e1 )" } if {$c2=="t1"} { set rhs "( $e2 )" } else { set rhs "$c2 : ( $e2 )" } set q1 "t1 MATCH '($lhs) AND ($rhs)'" set q2 "$c1 MATCH '$e1' AND $c2 MATCH '$e2'" set ret [execsql "SELECT rowid FROM t1 WHERE $q1"] set N [llength $ret] do_execsql_test 1.$tn.1.($N) "SELECT rowid FROM t1 WHERE $q2" $ret set ret [execsql "SELECT fts5_test_poslist(t1) FROM t1 WHERE $q1"] do_execsql_test 1.$tn.2.($N) " SELECT fts5_test_poslist(t1) FROM t1 WHERE $q2 " $ret } do_catchsql_test 2.1.1 { SELECT rowid FROM t1 WHERE t1 MATCH '(NOT' AND t1 MATCH 'aa bb'; } {1 {fts5: syntax error near "NOT"}} do_catchsql_test 2.1.2 { SELECT rowid FROM t1 WHERE t1 MATCH 'aa bb' AND t1 MATCH '(NOT'; } {1 {fts5: syntax error near "NOT"}} finish_test |
Changes to ext/fts5/test/fts5plan.test.
︙ | ︙ | |||
27 28 29 30 31 32 33 | } do_eqp_test 1.1 { SELECT * FROM t1, f1 WHERE f1 MATCH t1.x } { QUERY PLAN |--SCAN TABLE t1 | | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | } do_eqp_test 1.1 { SELECT * FROM t1, f1 WHERE f1 MATCH t1.x } { QUERY PLAN |--SCAN TABLE t1 `--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m } do_eqp_test 1.2 { SELECT * FROM t1, f1 WHERE f1 > t1.x } { QUERY PLAN |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0: `--SCAN TABLE t1 } do_eqp_test 1.3 { SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff } { QUERY PLAN |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m `--USE TEMP B-TREE FOR ORDER BY } do_eqp_test 1.4 { SELECT * FROM f1 ORDER BY rank } { QUERY PLAN |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0: `--USE TEMP B-TREE FOR ORDER BY } do_eqp_test 1.5 { SELECT * FROM f1 WHERE rank MATCH ? } {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:r} finish_test |
Changes to ext/fts5/test/fts5rank.test.
︙ | ︙ | |||
157 158 159 160 161 162 163 164 165 | ) INSERT INTO ttt SELECT 'word ' || i FROM s; } do_execsql_test 5.1 { SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank; } {30 31 32 33 34 35 36 37 38 39 40} finish_test | > > > > > > > > > > > > > > > > > > | 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 | ) INSERT INTO ttt SELECT 'word ' || i FROM s; } do_execsql_test 5.1 { SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank; } {30 31 32 33 34 35 36 37 38 39 40} #------------------------------------------------------------------------- reset_db do_execsql_test 6.0 { CREATE VIRTUAL TABLE "My.Table" USING fts5(Text); INSERT INTO "My.Table" VALUES ('hello this is a test'); INSERT INTO "My.Table" VALUES ('of trying to order by'); INSERT INTO "My.Table" VALUES ('rank on an fts5 table'); INSERT INTO "My.Table" VALUES ('that have periods in'); INSERT INTO "My.Table" VALUES ('the table names.'); INSERT INTO "My.Table" VALUES ('table table table'); } do_execsql_test 6.1 { SELECT * FROM "My.Table" WHERE Text MATCH 'table' ORDER BY rank; } { {table table table} {the table names.} {rank on an fts5 table} } finish_test |
Changes to ext/fts5/test/fts5simple.test.
︙ | ︙ | |||
463 464 465 466 467 468 469 470 | } {11111 11112} do_execsql_test 21.3 { DELETE FROM x1 WHERE rowid=11111; INSERT INTO x1(x1) VALUES('integrity-check'); SELECT rowid FROM x1($doc); } {11112} finish_test | > > > > > > > > > > > > > | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | } {11111 11112} do_execsql_test 21.3 { DELETE FROM x1 WHERE rowid=11111; INSERT INTO x1(x1) VALUES('integrity-check'); SELECT rowid FROM x1($doc); } {11112} #------------------------------------------------------------------------- reset_db do_execsql_test 22.0 { CREATE VIRTUAL TABLE x1 USING fts5(x); INSERT INTO x1(x) VALUES('a b c'); INSERT INTO x1(x) VALUES('x y z'); INSERT INTO x1(x) VALUES('c b a'); INSERT INTO x1(x) VALUES('z y x'); } do_catchsql_test 22.1 {SELECT * FROM x1('')} {1 {fts5: syntax error near ""}} do_catchsql_test 22.2 {SELECT * FROM x1(NULL)} {1 {fts5: syntax error near ""}} finish_test |
Changes to ext/lsm1/Makefile.
︙ | ︙ | |||
39 40 41 42 43 44 45 | $(LSMDIR)/lsm-test/lsmtest_main.c $(LSMDIR)/lsm-test/lsmtest_mem.c \ $(LSMDIR)/lsm-test/lsmtest_tdb.c $(LSMDIR)/lsm-test/lsmtest_tdb3.c \ $(LSMDIR)/lsm-test/lsmtest_util.c $(LSMDIR)/lsm-test/lsmtest_win32.c # all: lsm.so | | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | $(LSMDIR)/lsm-test/lsmtest_main.c $(LSMDIR)/lsm-test/lsmtest_mem.c \ $(LSMDIR)/lsm-test/lsmtest_tdb.c $(LSMDIR)/lsm-test/lsmtest_tdb3.c \ $(LSMDIR)/lsm-test/lsmtest_util.c $(LSMDIR)/lsm-test/lsmtest_win32.c # all: lsm.so LSMOPTS += -fPIC -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB lsm.so: $(LSMOBJ) $(TCCX) -shared -fPIC -o lsm.so $(LSMOBJ) %.o: $(LSMDIR)/%.c $(LSMHDR) sqlite3.h $(TCCX) $(LSMOPTS) -c $< lsmtest$(EXE): $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) sqlite3.o # $(TCPPX) -c $(TOP)/lsm-test/lsmtest_tdb2.cc $(TCCX) $(LSMOPTS) $(LSMTESTSRC) $(LSMOBJ) sqlite3.o -o lsmtest$(EXE) $(THREADLIB) -lz |
Changes to ext/lsm1/lsm_vtab.c.
︙ | ︙ | |||
838 839 840 841 842 843 844 | int argIdx = -1; /* Index of the key== constraint, or -1 if none */ int iIdx2 = -1; /* The index of the second key */ int omit1 = 0; int omit2 = 0; const struct sqlite3_index_constraint *pConstraint; pConstraint = pIdxInfo->aConstraint; | | | 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 | int argIdx = -1; /* Index of the key== constraint, or -1 if none */ int iIdx2 = -1; /* The index of the second key */ int omit1 = 0; int omit2 = 0; const struct sqlite3_index_constraint *pConstraint; pConstraint = pIdxInfo->aConstraint; for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ if( pConstraint->usable==0 ) continue; if( pConstraint->iColumn!=0 ) continue; switch( pConstraint->op ){ case SQLITE_INDEX_CONSTRAINT_EQ: { if( idxNum>0 ){ argIdx = i; iIdx2 = -1; |
︙ | ︙ |
Changes to ext/lsm1/test/lsm1_simple.test.
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 93 | 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 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | INSERT INTO x1(a,b,c,d) VALUES(15, 11, 22, 33),(8,'banjo',x'333231',NULL), (12,NULL,3.25,-559281390); SELECT quote(a), quote(b), quote(c), quote(d), '|' FROM x1; } {'12' NULL 3.25 -559281390 | '15' 11 22 33 | '8' 'banjo' X'333231' NULL |} do_execsql_test 211 { SELECT quote(a), quote(lsm1_key), quote(lsm1_value), '|' FROM x1; } {'12' X'3132' X'05320000000000000A401FFB42ABE9DB' | '15' X'3135' X'4284C6' | '8' X'38' X'2162616E6A6F1633323105' |} do_execsql_test 212 { SELECT quote(a), quote(lsm1_key), quote(lsm1_value) FROM x1 WHERE a='12'; } {'12' X'3132' X'05320000000000000A401FFB42ABE9DB'} #------------------------------------------------------------------------- reset_db forcedelete testlsm.db load_lsm1_vtab db do_execsql_test 300 { CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b,c,d); } do_eqp_test 310 { SELECT * FROM x1 WHERE a=? } {SCAN TABLE x1 VIRTUAL TABLE INDEX 0:} do_eqp_test 320 { SELECT * FROM x1 WHERE a>? } {SCAN TABLE x1 VIRTUAL TABLE INDEX 2:} do_eqp_test 330 { SELECT * FROM x1 WHERE a<? } {SCAN TABLE x1 VIRTUAL TABLE INDEX 3:} do_eqp_test 340 { SELECT * FROM x1 WHERE a BETWEEN ? AND ? } {SCAN TABLE x1 VIRTUAL TABLE INDEX 1:} #------------------------------------------------------------------------- reset_db forcedelete testlsm.db load_lsm1_vtab db do_execsql_test 400 { CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b); INSERT INTO x1 VALUES('one', 1); INSERT INTO x1 VALUES('two', 2); INSERT INTO x1 VALUES('three', 3); INSERT INTO x1 VALUES('four', 4); INSERT INTO x1 VALUES('five', 5); } do_execsql_test 410 { SELECT b FROM x1 WHERE a = 'two' } {2} do_execsql_test 411 { SELECT b FROM x1 WHERE a = 'one' } {1} do_execsql_test 412 { SELECT b FROM x1 WHERE a = 'five' } {5} do_execsql_test 420 { SELECT b FROM x1 WHERE a BETWEEN 'one' AND 'three'; } {1 3} do_execsql_test 421 { SELECT b FROM x1 WHERE a BETWEEN 'five' AND 'two'; } {5 4 1 3 2} do_execsql_test 421 { SELECT b FROM x1 WHERE a > 'five'; } {4 1 3 2} do_execsql_test 421 { SELECT b FROM x1 WHERE a <= 'three'; } {3 1 4 5} finish_test |
Changes to ext/misc/carray.c.
︙ | ︙ | |||
20 21 22 23 24 25 26 | ** at the address $ptr. $ptr is a pointer to the array of integers. ** The pointer value must be assigned to $ptr using the ** sqlite3_bind_pointer() interface with a pointer type of "carray". ** For example: ** ** static int aX[] = { 53, 9, 17, 2231, 4, 99 }; ** int i = sqlite3_bind_parameter_index(pStmt, "$ptr"); | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ** at the address $ptr. $ptr is a pointer to the array of integers. ** The pointer value must be assigned to $ptr using the ** sqlite3_bind_pointer() interface with a pointer type of "carray". ** For example: ** ** static int aX[] = { 53, 9, 17, 2231, 4, 99 }; ** int i = sqlite3_bind_parameter_index(pStmt, "$ptr"); ** sqlite3_bind_pointer(pStmt, i, aX, "carray", 0); ** ** There is an optional third parameter to determine the datatype of ** the C-language array. Allowed values of the third parameter are ** 'int32', 'int64', 'double', 'char*'. Example: ** ** SELECT * FROM carray($ptr,10,'char*'); ** |
︙ | ︙ |
Changes to ext/misc/fossildelta.c.
︙ | ︙ | |||
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | */ #include <string.h> #include <assert.h> #include <stdlib.h> #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 /* ** The "u32" type must be an unsigned 32-bit integer. Adjust this */ typedef unsigned int u32; /* ** Must be a 16-bit value */ typedef short int s16; typedef unsigned short int u16; /* ** The width of a hash window in bytes. The algorithm only works if this ** is a power of 2. */ #define NHASH 16 | > > > | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | */ #include <string.h> #include <assert.h> #include <stdlib.h> #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #ifndef SQLITE_AMALGAMATION /* ** The "u32" type must be an unsigned 32-bit integer. Adjust this */ typedef unsigned int u32; /* ** Must be a 16-bit value */ typedef short int s16; typedef unsigned short int u16; #endif /* SQLITE_AMALGAMATION */ /* ** The width of a hash window in bytes. The algorithm only works if this ** is a power of 2. */ #define NHASH 16 |
︙ | ︙ |
Changes to ext/misc/json1.c.
︙ | ︙ | |||
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 | int *pApnd, /* Append nodes to complete path if not NULL */ const char **pzErr /* Make *pzErr point to any syntax error in zPath */ ){ u32 i, j, nKey; const char *zKey; JsonNode *pRoot = &pParse->aNode[iRoot]; if( zPath[0]==0 ) return pRoot; if( zPath[0]=='.' ){ if( pRoot->eType!=JSON_OBJECT ) return 0; zPath++; if( zPath[0]=='"' ){ zKey = zPath + 1; for(i=1; zPath[i] && zPath[i]!='"'; i++){} nKey = i-1; | > | 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 | int *pApnd, /* Append nodes to complete path if not NULL */ const char **pzErr /* Make *pzErr point to any syntax error in zPath */ ){ u32 i, j, nKey; const char *zKey; JsonNode *pRoot = &pParse->aNode[iRoot]; if( zPath[0]==0 ) return pRoot; if( pRoot->jnFlags & JNODE_REPLACE ) return 0; if( zPath[0]=='.' ){ if( pRoot->eType!=JSON_OBJECT ) return 0; zPath++; if( zPath[0]=='"' ){ zKey = zPath + 1; for(i=1; zPath[i] && zPath[i]!='"'; i++){} nKey = i-1; |
︙ | ︙ | |||
1815 1816 1817 1818 1819 1820 1821 | JsonString *pStr; UNUSED_PARAM(argc); pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ jsonInit(pStr, ctx); jsonAppendChar(pStr, '['); | | | 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 | JsonString *pStr; UNUSED_PARAM(argc); pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ jsonInit(pStr, ctx); jsonAppendChar(pStr, '['); }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); pStr->pCtx = ctx; } jsonAppendValue(pStr, argv[0]); } } static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ |
︙ | ︙ | |||
1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 | 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; | > > | | > > > | | > > > | 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 | static void jsonGroupInverse( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ int i; int inStr = 0; int nNest = 0; char *z; char c; JsonString *pStr; UNUSED_PARAM(argc); UNUSED_PARAM(argv); pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); #ifdef NEVER /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will ** always have been called to initalize it */ if( NEVER(!pStr) ) return; #endif z = pStr->zBuf; for(i=1; (c = z[i])!=',' || inStr || nNest; i++){ if( i>=pStr->nUsed ){ pStr->nUsed = 1; return; } if( c=='"' ){ inStr = !inStr; }else if( c=='\\' ){ i++; }else if( !inStr ){ if( c=='{' || c=='[' ) nNest++; if( c=='}' || c==']' ) nNest--; } } pStr->nUsed -= i; memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1); } #else # define jsonGroupInverse 0 |
︙ | ︙ | |||
1911 1912 1913 1914 1915 1916 1917 | u32 n; UNUSED_PARAM(argc); pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ jsonInit(pStr, ctx); jsonAppendChar(pStr, '{'); | | | 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 | u32 n; UNUSED_PARAM(argc); pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ jsonInit(pStr, ctx); jsonAppendChar(pStr, '{'); }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); pStr->pCtx = ctx; } z = (const char*)sqlite3_value_text(argv[0]); n = (u32)sqlite3_value_bytes(argv[0]); jsonAppendString(pStr, z, n); jsonAppendChar(pStr, ':'); |
︙ | ︙ | |||
2499 2500 2501 2502 2503 2504 2505 | } aMod[] = { { "json_each", &jsonEachModule }, { "json_tree", &jsonTreeModule }, }; #endif for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, | | | | 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 | } aMod[] = { { "json_each", &jsonEachModule }, { "json_tree", &jsonTreeModule }, }; #endif for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, SQLITE_UTF8 | SQLITE_DETERMINISTIC, (void*)&aFunc[i].flag, aFunc[i].xFunc, 0, 0); } #ifndef SQLITE_OMIT_WINDOWFUNC for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){ rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg, SQLITE_SUBTYPE | SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, aAgg[i].xStep, aAgg[i].xFinal, aAgg[i].xValue, jsonGroupInverse, 0); } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){ rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0); |
︙ | ︙ |
Changes to ext/misc/regexp.c.
︙ | ︙ | |||
606 607 608 609 610 611 612 | return 0; } /* Free and reclaim all the memory used by a previously compiled ** regular expression. Applications should invoke this routine once ** for every call to re_compile() to avoid memory leaks. */ | | | | 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 | return 0; } /* Free and reclaim all the memory used by a previously compiled ** regular expression. Applications should invoke this routine once ** for every call to re_compile() to avoid memory leaks. */ static void re_free(ReCompiled *pRe){ if( pRe ){ sqlite3_free(pRe->aOp); sqlite3_free(pRe->aArg); sqlite3_free(pRe); } } /* ** Compile a textual regular expression in zIn[] into a compiled regular ** expression suitable for us by re_match() and return a pointer to the ** compiled regular expression in *ppRe. Return NULL on success or an ** error message if something goes wrong. */ static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ ReCompiled *pRe; const char *zErr; int i, j; *ppRe = 0; pRe = sqlite3_malloc( sizeof(*pRe) ); if( pRe==0 ){ |
︙ | ︙ |
Added ext/rbu/rbuexpr.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | # 2014 August 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # source [file join [file dirname [info script]] rbu_common.tcl] set ::testprefix rbuexpr db close sqlite3_shutdown sqlite3_config_uri 1 sqlite3 db test.db do_execsql_test 1.0 { CREATE TABLE t1(a, b, c PRIMARY KEY); CREATE INDEX i1 ON t1(a, null, b+1); CREATE INDEX i2 ON t1(a+1, b+1, c+1); INSERT INTO t1 VALUES(1, 2, 3); INSERT INTO t1 VALUES(4, 5, 6); INSERT INTO t1 VALUES(7, 8, 9); INSERT INTO t1 VALUES(10, 11, 12); PRAGMA integrity_check; } {ok} forcedelete rbu.db sqlite3 db2 rbu.db do_execsql_test -db db2 1.1 { CREATE TABLE data_t1(a, b, c, rbu_control); INSERT INTO data_t1 VALUES(13, 14, 15, 0); INSERT INTO data_t1 VALUES(NULL, NULL, 6, 1); INSERT INTO data_t1 VALUES(NULL, 'three', 3, '.x.'); } db2 close db close do_test 1.2 { run_rbu test.db rbu.db } {SQLITE_DONE} sqlite3 db test.db do_execsql_test 1.3 { SELECT * FROM t1 WHERE a=4; } integrity_check 1.4 #------------------------------------------------------------------------- # reset_db do_execsql_test 2.0 { CREATE TABLE t1(c1, c2, c3, i INTEGER PRIMARY KEY); INSERT INTO t1 VALUES('one', 'one', 'one', 1); INSERT INTO t1 VALUES('two', 'two', 'two', 2); INSERT INTO t1 VALUES('three', 'three', 'three', 3); INSERT INTO t1 VALUES('four', 'four', 'four', 4); CREATE INDEX i1 ON t1( substr(c1, 1, 2) ); CREATE INDEX i2 ON t1( c1 || c2 || c3 ); CREATE INDEX i3 ON t1( length(c1) + length(c2) - 1, c3||i ); } forcedelete rbu.db sqlite3 db2 rbu.db do_execsql_test -db db2 2.1 { CREATE TABLE data_t1(c1, c2, c3, i, rbu_control); INSERT INTO data_t1 VALUES(NULL, NULL, NULL, 2, 1); INSERT INTO data_t1 VALUES('thirty', NULL, NULL, 3, 'xx..'); INSERT INTO data_t1 VALUES('five', 'five', 'five', 5, 0); } db2 close db close do_test 2.2 { run_rbu test.db rbu.db } {SQLITE_DONE} sqlite3 db test.db integrity_check 2.3 finish_test |
Changes to ext/rbu/rbupartial.test.
︙ | ︙ | |||
36 37 38 39 40 41 42 43 44 45 46 47 48 49 | CREATE INDEX i1b3 ON t1(%B%) WHERE %C%>=5; CREATE INDEX i1c ON t1(%C%); CREATE INDEX i1c2 ON t1(%C%) WHERE %C% IS NULL; CREATE INDEX i1c3 ON t1(%C%) WHERE %C% IS NOT NULL; CREATE INDEX i1c4 ON t1(%C%) WHERE %D% < 'd'; } do_execsql_test $tn.1.1 { INSERT INTO t1 VALUES(0, NULL, NULL, 'a'); INSERT INTO t1 VALUES(1, 2, 3, 'b'); INSERT INTO t1 VALUES(4, 5, 6, 'c'); INSERT INTO t1 VALUES(7, 8, 9, 'd'); | > > > > > > > > > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | CREATE INDEX i1b3 ON t1(%B%) WHERE %C%>=5; CREATE INDEX i1c ON t1(%C%); CREATE INDEX i1c2 ON t1(%C%) WHERE %C% IS NULL; CREATE INDEX i1c3 ON t1(%C%) WHERE %C% IS NOT NULL; CREATE INDEX i1c4 ON t1(%C%) WHERE %D% < 'd'; CREATE INDEX i1c5 ON t1( %C% -- for (c = ... expressions ) WHERE %D% < 'd'; CREATE INDEX i1c6 ON t1( %C% /* Again, for (c=... expr */, %D% ) WHERE %D% < 'd'; CREATE INDEX i1c7 ON t1( %C% /* As before, for (c=... "expr */) WHERE %D% < 'd'; } do_execsql_test $tn.1.1 { INSERT INTO t1 VALUES(0, NULL, NULL, 'a'); INSERT INTO t1 VALUES(1, 2, 3, 'b'); INSERT INTO t1 VALUES(4, 5, 6, 'c'); INSERT INTO t1 VALUES(7, 8, 9, 'd'); |
︙ | ︙ |
Changes to ext/rbu/rbuprogress.test.
︙ | ︙ | |||
409 410 411 412 413 414 415 416 417 418 | set R(nopk) $r1 set R(vtab) $r2 do_sp_test 5.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn) } } } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | set R(nopk) $r1 set R(vtab) $r2 do_sp_test 5.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn) } } } #------------------------------------------------------------------------- # Test that sqlite3_bp_progress() works with an RBU vacuum if there # is an rbu_count table in the db being vacuumed. # reset_db do_execsql_test 6.0 { CREATE TABLE t1(a, b, c); CREATE INDEX i1 ON t1(a); CREATE INDEX i2 ON t1(b); WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 ) INSERT INTO t1 SELECT i, i, i FROM s; CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; INSERT INTO rbu_count VALUES('t1', (SELECT count(*) FROM t1)); INSERT INTO rbu_count VALUES('rbu_count', 2); } forcedelete state.db do_test 6.1 { set maxA 0 set maxB 0 sqlite3rbu_vacuum rbu test.db state.db while {[rbu step]=="SQLITE_OK"} { foreach {a b} [rbu bp_progress] { if {$a > $maxA} { set maxA $a } if {$b > $maxB} { set maxB $b } } } list [rbu close] $maxA $maxB } {SQLITE_DONE 10000 10000} finish_test |
Changes to ext/rbu/sqlite3rbu.c.
︙ | ︙ | |||
178 179 180 181 182 183 184 185 186 187 188 189 190 191 | #define RBU_CREATE_STATE \ "CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)" typedef struct RbuFrame RbuFrame; typedef struct RbuObjIter RbuObjIter; typedef struct RbuState RbuState; typedef struct rbu_vfs rbu_vfs; typedef struct rbu_file rbu_file; typedef struct RbuUpdateStmt RbuUpdateStmt; #if !defined(SQLITE_AMALGAMATION) typedef unsigned int u32; typedef unsigned short u16; | > | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | #define RBU_CREATE_STATE \ "CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)" typedef struct RbuFrame RbuFrame; typedef struct RbuObjIter RbuObjIter; typedef struct RbuState RbuState; typedef struct RbuSpan RbuSpan; typedef struct rbu_vfs rbu_vfs; typedef struct rbu_file rbu_file; typedef struct RbuUpdateStmt RbuUpdateStmt; #if !defined(SQLITE_AMALGAMATION) typedef unsigned int u32; typedef unsigned short u16; |
︙ | ︙ | |||
221 222 223 224 225 226 227 228 229 230 231 232 233 234 | }; struct RbuUpdateStmt { char *zMask; /* Copy of update mask used with pUpdate */ sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ RbuUpdateStmt *pNext; }; /* ** An iterator of this type is used to iterate through all objects in ** the target database that require updating. For each such table, the ** iterator visits, in order: ** ** * the table itself, | > > > > > | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | }; struct RbuUpdateStmt { char *zMask; /* Copy of update mask used with pUpdate */ sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ RbuUpdateStmt *pNext; }; struct RbuSpan { const char *zSpan; int nSpan; }; /* ** An iterator of this type is used to iterate through all objects in ** the target database that require updating. For each such table, the ** iterator visits, in order: ** ** * the table itself, |
︙ | ︙ | |||
271 272 273 274 275 276 277 278 279 280 281 282 283 284 | /* Statements created by rbuObjIterPrepareAll() */ int nCol; /* Number of columns in current object */ sqlite3_stmt *pSelect; /* Source data */ sqlite3_stmt *pInsert; /* Statement for INSERT operations */ sqlite3_stmt *pDelete; /* Statement for DELETE ops */ sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */ /* Last UPDATE used (for PK b-tree updates only), or NULL. */ RbuUpdateStmt *pRbuUpdate; }; /* ** Values for RbuObjIter.eType | > > > | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | /* Statements created by rbuObjIterPrepareAll() */ int nCol; /* Number of columns in current object */ sqlite3_stmt *pSelect; /* Source data */ sqlite3_stmt *pInsert; /* Statement for INSERT operations */ sqlite3_stmt *pDelete; /* Statement for DELETE ops */ sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */ int nIdxCol; RbuSpan *aIdxCol; char *zIdxSql; /* Last UPDATE used (for PK b-tree updates only), or NULL. */ RbuUpdateStmt *pRbuUpdate; }; /* ** Values for RbuObjIter.eType |
︙ | ︙ | |||
805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 | pUp = pIter->pRbuUpdate; while( pUp ){ RbuUpdateStmt *pTmp = pUp->pNext; sqlite3_finalize(pUp->pUpdate); sqlite3_free(pUp); pUp = pTmp; } pIter->pSelect = 0; pIter->pInsert = 0; pIter->pDelete = 0; pIter->pRbuUpdate = 0; pIter->pTmpInsert = 0; pIter->nCol = 0; } /* ** Clean up any resources allocated as part of the iterator object passed ** as the only argument. */ static void rbuObjIterFinalize(RbuObjIter *pIter){ | > > > > > | 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 | pUp = pIter->pRbuUpdate; while( pUp ){ RbuUpdateStmt *pTmp = pUp->pNext; sqlite3_finalize(pUp->pUpdate); sqlite3_free(pUp); pUp = pTmp; } sqlite3_free(pIter->aIdxCol); sqlite3_free(pIter->zIdxSql); pIter->pSelect = 0; pIter->pInsert = 0; pIter->pDelete = 0; pIter->pRbuUpdate = 0; pIter->pTmpInsert = 0; pIter->nCol = 0; pIter->nIdxCol = 0; pIter->aIdxCol = 0; pIter->zIdxSql = 0; } /* ** Clean up any resources allocated as part of the iterator object passed ** as the only argument. */ static void rbuObjIterFinalize(RbuObjIter *pIter){ |
︙ | ︙ | |||
926 927 928 929 930 931 932 | sqlite3rbu *p = sqlite3_user_data(pCtx); const char *zIn; assert( argc==1 || argc==2 ); zIn = (const char*)sqlite3_value_text(argv[0]); if( zIn ){ if( rbuIsVacuum(p) ){ | | | | 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 | sqlite3rbu *p = sqlite3_user_data(pCtx); const char *zIn; assert( argc==1 || argc==2 ); zIn = (const char*)sqlite3_value_text(argv[0]); if( zIn ){ if( rbuIsVacuum(p) ){ assert( argc==2 || argc==1 ); if( argc==1 || 0==sqlite3_value_int(argv[1]) ){ sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC); } }else{ if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){ int i; for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++); if( zIn[i]=='_' && zIn[i+1] ){ |
︙ | ︙ | |||
1085 1086 1087 1088 1089 1090 1091 | ** If an OOM condition is encountered when attempting to allocate memory, ** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise, ** if the allocation succeeds, (*pRc) is left unchanged. */ static char *rbuStrndup(const char *zStr, int *pRc){ char *zRet = 0; | | | | | | | | | > | 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 | ** If an OOM condition is encountered when attempting to allocate memory, ** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise, ** if the allocation succeeds, (*pRc) is left unchanged. */ static char *rbuStrndup(const char *zStr, int *pRc){ char *zRet = 0; if( *pRc==SQLITE_OK ){ if( zStr ){ size_t nCopy = strlen(zStr) + 1; zRet = (char*)sqlite3_malloc64(nCopy); if( zRet ){ memcpy(zRet, zStr, nCopy); }else{ *pRc = SQLITE_NOMEM; } } } return zRet; } /* |
︙ | ︙ | |||
1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 | } p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ int iCid = sqlite3_column_int(pXInfo, 1); if( iCid>=0 ) pIter->abIndexed[iCid] = 1; } rbuFinalize(p, pXInfo); bIndex = 1; pIter->nIndex++; } if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ | > > > | 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 | } p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ int iCid = sqlite3_column_int(pXInfo, 1); if( iCid>=0 ) pIter->abIndexed[iCid] = 1; if( iCid==-2 ){ memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol); } } rbuFinalize(p, pXInfo); bIndex = 1; pIter->nIndex++; } if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ |
︙ | ︙ | |||
1675 1676 1677 1678 1679 1680 1681 | ); } while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ int iCid = sqlite3_column_int(pXInfo, 1); int bDesc = sqlite3_column_int(pXInfo, 3); const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); | | > > > > > > > | | | | | | | | | | | | | | | | | | > | | | 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 | ); } while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ int iCid = sqlite3_column_int(pXInfo, 1); int bDesc = sqlite3_column_int(pXInfo, 3); const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); const char *zCol = 0; const char *zType; if( iCid==-2 ){ int iSeq = sqlite3_column_int(pXInfo, 0); zRet = sqlite3_mprintf("%z%s(%.*s) COLLATE %Q", zRet, zCom, pIter->aIdxCol[iSeq].nSpan, pIter->aIdxCol[iSeq].zSpan, zCollate ); zType = ""; }else { if( iCid<0 ){ /* An integer primary key. If the table has an explicit IPK, use ** its name. Otherwise, use "rbu_rowid". */ if( pIter->eType==RBU_PK_IPK ){ int i; for(i=0; pIter->abTblPk[i]==0; i++); assert( i<pIter->nTblCol ); zCol = pIter->azTblCol[i]; }else if( rbuIsVacuum(p) ){ zCol = "_rowid_"; }else{ zCol = "rbu_rowid"; } zType = "INTEGER"; }else{ zCol = pIter->azTblCol[iCid]; zType = pIter->azTblType[iCid]; } zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom,zCol,zCollate); } if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){ const char *zOrder = (bDesc ? " DESC" : ""); zImpPK = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s", zImpPK, zCom, nBind, zCol, zOrder ); } zImpCols = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\" %s COLLATE %Q", |
︙ | ︙ | |||
2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 | } static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){ sqlite3_stmt *pStmt = 0; int rc = p->rc; char *zRet = 0; if( rc==SQLITE_OK ){ rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, "SELECT trim(sql) FROM sqlite_master WHERE type='index' AND name=?" ); } if( rc==SQLITE_OK ){ int rc2; rc = sqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC); if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 | } static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){ sqlite3_stmt *pStmt = 0; int rc = p->rc; char *zRet = 0; assert( pIter->zIdxSql==0 && pIter->nIdxCol==0 && pIter->aIdxCol==0 ); if( rc==SQLITE_OK ){ rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, "SELECT trim(sql) FROM sqlite_master WHERE type='index' AND name=?" ); } if( rc==SQLITE_OK ){ int rc2; rc = sqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC); if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ char *zSql = (char*)sqlite3_column_text(pStmt, 0); if( zSql ){ pIter->zIdxSql = zSql = rbuStrndup(zSql, &rc); } if( zSql ){ int nParen = 0; /* Number of open parenthesis */ int i; int iIdxCol = 0; int nIdxAlloc = 0; for(i=0; zSql[i]; i++){ char c = zSql[i]; /* If necessary, grow the pIter->aIdxCol[] array */ if( iIdxCol==nIdxAlloc ){ RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc( pIter->aIdxCol, (nIdxAlloc+16)*sizeof(RbuSpan) ); if( aIdxCol==0 ){ rc = SQLITE_NOMEM; break; } pIter->aIdxCol = aIdxCol; nIdxAlloc += 16; } if( c=='(' ){ if( nParen==0 ){ assert( iIdxCol==0 ); pIter->aIdxCol[0].zSpan = &zSql[i+1]; } nParen++; } else if( c==')' ){ nParen--; if( nParen==0 ){ int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; pIter->aIdxCol[iIdxCol++].nSpan = nSpan; i++; break; } }else if( c==',' && nParen==1 ){ int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; pIter->aIdxCol[iIdxCol++].nSpan = nSpan; pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1]; }else if( c=='"' || c=='\'' || c=='`' ){ for(i++; 1; i++){ if( zSql[i]==c ){ if( zSql[i+1]!=c ) break; i++; } } }else if( c=='[' ){ for(i++; 1; i++){ if( zSql[i]==']' ) break; } }else if( c=='-' && zSql[i+1]=='-' ){ for(i=i+2; zSql[i] && zSql[i]!='\n'; i++); if( zSql[i]=='\0' ) break; }else if( c=='/' && zSql[i+1]=='*' ){ for(i=i+2; zSql[i] && (zSql[i]!='*' || zSql[i+1]!='/'); i++); if( zSql[i]=='\0' ) break; i++; } } if( zSql[i] ){ zRet = rbuStrndup(&zSql[i], &rc); } pIter->nIdxCol = iIdxCol; } } rc2 = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ) rc = rc2; } |
︙ | ︙ | |||
2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 | char *zImposterPK = 0; /* Primary key declaration for imposter */ char *zWhere = 0; /* WHERE clause on PK columns */ char *zBind = 0; char *zPart = 0; int nBind = 0; assert( pIter->eType!=RBU_PK_VTAB ); zCollist = rbuObjIterGetIndexCols( p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind ); zBind = rbuObjIterGetBindlist(p, nBind); | > < | 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 | char *zImposterPK = 0; /* Primary key declaration for imposter */ char *zWhere = 0; /* WHERE clause on PK columns */ char *zBind = 0; char *zPart = 0; int nBind = 0; assert( pIter->eType!=RBU_PK_VTAB ); zPart = rbuObjIterGetIndexWhere(p, pIter); zCollist = rbuObjIterGetIndexCols( p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind ); zBind = rbuObjIterGetBindlist(p, nBind); /* Create the imposter table used to write to this index. */ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum); rbuMPrintfExec(p, p->dbMain, "CREATE TABLE \"rbu_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID", zTbl, zImposterCols, zImposterPK |
︙ | ︙ | |||
3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 | int nVal, sqlite3_value **apVal ){ sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx); sqlite3_stmt *pStmt = 0; char *zErrmsg = 0; int rc; assert( nVal==1 ); | > | | | 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 | int nVal, sqlite3_value **apVal ){ sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx); sqlite3_stmt *pStmt = 0; char *zErrmsg = 0; int rc; sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); assert( nVal==1 ); rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg, sqlite3_mprintf("SELECT count(*) FROM sqlite_master " "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0])) ); if( rc!=SQLITE_OK ){ sqlite3_result_error(pCtx, zErrmsg, -1); }else{ int nIndex = 0; if( SQLITE_ROW==sqlite3_step(pStmt) ){ nIndex = sqlite3_column_int(pStmt, 0); } rc = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ){ sqlite3_result_int(pCtx, nIndex); }else{ sqlite3_result_error(pCtx, sqlite3_errmsg(db), -1); } } sqlite3_free(zErrmsg); } /* |
︙ | ︙ |
Changes to ext/rtree/rtree.c.
︙ | ︙ | |||
665 666 667 668 669 670 671 | int rc = SQLITE_OK; RtreeNode *pNode = 0; /* Check if the requested node is already in the hash table. If so, ** increase its reference count and return it. */ if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ | < > > > | 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 | int rc = SQLITE_OK; RtreeNode *pNode = 0; /* Check if the requested node is already in the hash table. If so, ** increase its reference count and return it. */ if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ if( pParent && !pNode->pParent ){ if( nodeInParentChain(pNode, pParent) ){ RTREE_IS_CORRUPT(pRtree); return SQLITE_CORRUPT_VTAB; } pParent->nRef++; pNode->pParent = pParent; }else if( pParent && pNode->pParent && pParent!=pNode->pParent ){ RTREE_IS_CORRUPT(pRtree); return SQLITE_CORRUPT_VTAB; } pNode->nRef++; *ppNode = pNode; return SQLITE_OK; } if( pRtree->pNodeBlob ){ |
︙ | ︙ | |||
1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 | int nConstraint = pCur->nConstraint; int ii; int eInt; RtreeSearchPoint x; eInt = pRtree->eCoordType==RTREE_COORD_INT32; while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); if( rc ) return rc; nCell = NCELL(pNode); assert( nCell<200 ); while( p->iCell<nCell ){ sqlite3_rtree_dbl rScore = (sqlite3_rtree_dbl)-1; | > > < | < | > > > > > > > > > > > | 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 | int nConstraint = pCur->nConstraint; int ii; int eInt; RtreeSearchPoint x; eInt = pRtree->eCoordType==RTREE_COORD_INT32; while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ u8 *pCellData; pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); if( rc ) return rc; nCell = NCELL(pNode); assert( nCell<200 ); pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell); while( p->iCell<nCell ){ sqlite3_rtree_dbl rScore = (sqlite3_rtree_dbl)-1; eWithin = FULLY_WITHIN; for(ii=0; ii<nConstraint; ii++){ RtreeConstraint *pConstraint = pCur->aConstraint + ii; if( pConstraint->op>=RTREE_MATCH ){ rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p, &rScore, &eWithin); if( rc ) return rc; }else if( p->iLevel==1 ){ rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin); }else{ rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin); } if( eWithin==NOT_WITHIN ){ p->iCell++; pCellData += pRtree->nBytesPerCell; break; } } if( eWithin==NOT_WITHIN ) continue; p->iCell++; x.iLevel = p->iLevel - 1; if( x.iLevel ){ x.id = readInt64(pCellData); for(ii=0; ii<pCur->nPoint; ii++){ if( pCur->aPoint[ii].id==x.id ){ RTREE_IS_CORRUPT(pRtree); return SQLITE_CORRUPT_VTAB; } } x.iCell = 0; }else{ x.id = p->id; x.iCell = p->iCell - 1; } if( p->iCell>=nCell ){ RTREE_QUEUE_TRACE(pCur, "POP-S:"); |
︙ | ︙ |
Changes to ext/rtree/rtreefuzz001.test.
︙ | ︙ | |||
461 462 463 464 465 466 467 468 469 470 471 472 473 474 | | 3392: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 07 74 A...A .........t | 3408: 41 00 00 00 41 10 00 00 41 10 00 00 41 20 00 00 A...A...A...A .. | 3424: 00 00 00 00 00 00 07 75 41 10 00 00 41 20 00 00 .......uA...A .. | 3440: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 00 00 A...A .......... | end c1b.db }] catchsql { SELECT rtreecheck('t1'); } } {1 {SQL logic error}} do_test rtreefuzz001-200 { sqlite3 db {} db deserialize [decode_hexdb { | > | 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 | | 3392: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 07 74 A...A .........t | 3408: 41 00 00 00 41 10 00 00 41 10 00 00 41 20 00 00 A...A...A...A .. | 3424: 00 00 00 00 00 00 07 75 41 10 00 00 41 20 00 00 .......uA...A .. | 3440: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 00 00 A...A .......... | end c1b.db }] catchsql { PRAGMA writable_schema = 1; SELECT rtreecheck('t1'); } } {1 {SQL logic error}} do_test rtreefuzz001-200 { sqlite3 db {} db deserialize [decode_hexdb { |
︙ | ︙ | |||
769 770 771 772 773 774 775 776 777 | WITH RECURSIVE c1(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c1 WHERE x<8), c2(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM c2 WHERE y<5) INSERT INTO t1(id, x0,x1,y0,y1,label) SELECT 1000+x+y*100, x, x+1, y, y+1, printf('box-%d,%d',x,y) FROM c1, c2; } } {1 {database disk image is malformed}} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 | WITH RECURSIVE c1(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c1 WHERE x<8), c2(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM c2 WHERE y<5) INSERT INTO t1(id, x0,x1,y0,y1,label) SELECT 1000+x+y*100, x, x+1, y, y+1, printf('box-%d,%d',x,y) FROM c1, c2; } } {1 {database disk image is malformed}} do_test rtreefuzz001-500 { sqlite3 db {} db deserialize [decode_hexdb { | size 16384 pagesize 4096 filename crash-2e81f5dce5cbd4.db | page 1 offset 0 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ | 96: 00 00 00 00 0d 00 00 00 05 0e 6d 00 0f c8 0f 7b ..........m..... | 112: 0f 20 0e cd 0e 6d 00 00 00 00 00 00 00 00 00 00 . ...m.......... | 3680: 00 00 00 00 00 00 00 00 00 00 00 00 00 5e 05 07 .............^.. | 3696: 17 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 ......tablet1_pa | 3712: 72 65 6e 74 74 31 5f 70 61 72 65 6e 74 05 43 52 rentt1_parent.CR | 3728: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 EATE TABLE .t1_p | 3744: 61 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e arent.(nodeno IN | 3760: 54 45 47 45 42 20 50 52 49 4d 41 52 59 20 4b 45 TEGEB PRIMARY KE | 3776: 59 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 04 06 Y,parentnode)Q.. | 3792: 17 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 .....tablet1_nod | 3808: 65 74 31 5f 6e 6f 64 65 04 43 52 45 41 54 45 20 et1_node.CREATE | 3824: 54 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 TABLE .t1_node.( | 3840: 6e 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 nodeno INTEGER P | 3856: 52 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 RIMARY KEY,data) | 3872: 59 03 07 17 1d 1d 01 81 05 74 61 62 6c 65 84 31 Y........table.1 | 3888: 5f 72 6f 77 69 64 74 31 5f 72 6f 87 69 64 03 43 _rowidt1_ro.id.C | 3904: 52 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f REATE TABLE .t1_ | 3920: 72 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 rowid.(rowid INT | 3936: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY | 3952: 2c 6e f8 64 65 6e 6f 2c 61 30 29 4b 02 07 17 11 ,n.deno,a0)K.... | 3968: 11 08 81 03 74 22 62 6c 65 74 31 74 31 43 52 45 ....t.blet1t1CRE | 3984: 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c ATE VIRTUAL TABL | 4000: 45 20 74 31 20 55 53 49 4e 47 20 72 74 72 65 65 E t1 USING rtree | 4016: 5f 69 33 32 28 69 cc 2c 78 30 2c 78 31 2c 79 30 _i32(i.,x0,x1,y0 | 4032: 2c 79 31 2c 2b 65 78 29 36 01 06 17 17 17 01 4d ,y1,+ex)6......M | 4048: 74 61 62 6c 65 63 6f 6f 72 64 63 6f 6f 72 64 02 tablecoordcoord. | 4064: 43 52 45 41 54 45 20 54 41 42 4c 45 20 63 6f 6f CREATE TABLE coo | 4080: 71 64 28 76 20 49 4e 54 2c 20 77 20 49 4e 54 29 qd(v INT, w INT) | page 2 offset 4096 | 4016: 00 00 00 00 00 00 00 00 00 00 00 05 0a 03 01 01 ................ | 4032: 0a 02 05 09 03 01 01 09 02 05 08 03 01 01 08 02 ................ | 4048: 05 07 03 01 01 07 02 05 06 03 11 01 06 02 05 05 ................ | 4064: 03 01 01 05 02 05 04 03 01 01 04 02 05 03 03 01 ................ | 4080: 01 03 02 05 02 03 01 01 02 02 04 01 03 09 01 02 ................ | page 3 offset 8192 | 0: 0d 0e 4f 00 64 0b 5a 12 0d bb 0d 84 0f eb 0d c6 ..O.d.Z......... | 16: 0f d7 0e cc 0f c1 0f b6 0f ab 0f 9f 0f 94 0d 8f ................ | 32: 0f 86 0d d1 0f 62 0f 67 0f 5c 0f 51 1f 46 0f 3a .....b.g...Q.F.: | 48: 0f 30 0d 9a 0f 21 0d dc 0f 00 00 00 00 00 00 00 .0...!.......... | 2896: 00 00 00 00 00 00 00 00 00 00 0a ce 1a 04 00 01 ................ | 2912: 17 03 31 30 78 31 30 0a 4e 19 03 ff f1 15 03 31 ..10x10.N......1 | 2928: 30 78 39 09 ce 18 04 00 01 15 03 31 30 78 38 09 0x9........10x8. | 2944: ce 17 04 00 01 15 03 31 30 78 37 09 ce 16 04 00 .......10x7..... | 2960: 12 15 03 31 30 78 36 09 ce 15 04 00 01 15 03 31 ...10x6........1 | 2976: 30 78 35 09 ce 14 04 00 01 15 0d a1 30 78 34 09 0x5.........0x4. | 2992: ce 13 04 00 01 15 03 31 30 78 33 09 ce 12 04 00 .......10x3..... | 3008: 01 15 03 31 40 78 32 09 ce 11 04 00 01 15 03 31 ...1@x2........1 | 3024: 30 78 31 09 c6 32 04 00 01 15 03 39 78 31 30 08 0x1..2.....9x10. | 3040: c6 31 04 00 01 13 03 39 78 39 08 c6 30 04 00 01 .1.....9x9..0... | 3056: 13 03 39 78 38 08 c6 2f 04 00 01 14 03 39 78 37 ..9x8../.....9x7 | 3072: 08 c6 2e 04 00 01 13 03 39 78 36 08 c6 2d 04 00 ........9x6..-.. | 3088: 01 13 03 39 78 34 f8 c6 2c 04 00 01 13 03 39 78 ...9x4..,.....9x | 3104: 34 08 c6 2b 04 00 60 13 03 39 79 13 08 c6 2a 04 4..+..`..9y...*. | 3120: 00 11 13 03 39 78 32 08 c6 29 04 00 01 13 03 39 ....9x2..).....9 | 3136: 78 31 09 be 4a 04 00 01 15 03 38 78 31 30 08 be x1..J.....8x10.. | 3152: 49 04 00 01 13 03 38 78 39 08 be 48 04 00 01 13 I.....8x9..H.... | 3168: 03 38 77 98 08 be 47 04 00 01 14 23 38 78 37 08 .8w...G....#8x7. | 3184: be 46 04 00 01 13 03 38 78 36 08 be 45 04 00 01 .F.....8x6..E... | 3200: 13 03 38 78 35 08 be 44 04 00 01 13 03 38 78 34 ..8x5..D.....8x4 | 3216: 08 be 43 04 00 01 13 03 38 78 33 08 be 42 04 00 ..C.....8x3..B.. | 3232: 01 13 03 38 78 32 08 be 41 04 00 01 13 03 38 78 ...8x2..A.....8x | 3248: 31 09 b6 62 04 00 01 15 03 37 68 31 30 08 b6 61 1..b.....7h10..a | 3264: 04 00 01 13 03 37 79 39 08 b6 60 04 00 01 12 f3 .....7y9..`..... | 3280: 37 78 38 08 b6 5e 04 00 01 13 03 37 78 37 08 b6 7x8..^.....7x7.. | 3296: 5e 04 00 01 13 03 37 78 36 08 b6 5d 04 00 01 13 ^.....7x6..].... | 3312: 03 37 78 35 08 b6 5c 04 00 00 13 03 37 78 34 08 .7x5........7x4. | 3328: b6 5b 04 00 01 13 03 37 78 33 08 b6 5a 04 00 01 .[.....7x3..Z... | 3344: 13 03 37 78 32 08 b6 59 04 00 01 13 03 37 78 31 ..7x2..Y.....7x1 | 3360: 09 ae 7a 04 00 01 15 03 36 78 31 30 08 ae 79 04 ..z.....6x10..y. | 3376: 00 01 e2 03 36 78 39 08 ae 78 04 00 01 13 03 36 ....6x9..x.....6 | 3392: 78 38 08 ae 77 04 00 01 13 03 36 78 37 08 ae 76 x8..w.....6x7..v | 3408: 04 00 01 13 03 36 78 36 08 ae 85 04 00 01 13 03 .....6x6........ | 3424: 36 78 35 08 ae 73 f4 00 01 13 03 36 78 34 08 ae 6x5..s.....6x4.. | 3440: 73 04 00 01 13 03 36 78 33 08 ae 72 04 00 01 13 s.....6x3..r.... | 3456: 03 36 78 32 08 87 6a 04 00 01 13 02 3d e8 32 08 .6x2..j.....=.2. | 3472: 8f 52 04 00 01 13 02 32 78 32 08 97 3b 04 00 01 .R.....2x2..;... | 3488: 13 02 33 78 32 08 9f 22 04 00 01 13 02 34 78 32 ..3x2........4x2 | 3504: 08 a7 0a 04 00 01 13 02 35 78 32 08 87 69 04 00 ........5x2..i.. | 3520: 01 13 02 31 78 31 08 87 6c 04 00 01 13 02 31 78 ...1x1..l.....1x | 3536: 34 08 8f 54 04 00 01 13 02 32 78 34 08 97 3c 04 4..T.....2x4..<. | 3552: 00 01 12 f2 33 78 34 08 9f 24 04 00 01 13 02 34 ....3x4..$.....4 | 3568: 78 34 08 a7 0c 04 00 01 13 02 35 78 34 0e 6c 00 x4........5x4.l. | 3584: 08 ae 71 04 00 01 13 03 36 78 31 09 a7 12 04 00 ..q.....6x1..... | 3600: 01 15 02 35 78 31 30 08 a7 11 04 00 01 13 02 35 ...5x10........5 | 3616: 78 39 08 a7 10 04 00 01 13 02 35 78 38 08 a7 0f x9........5x8... | 3632: 04 00 01 14 02 35 78 37 08 a7 0e 04 00 01 13 02 .....5x7........ | 3648: 35 78 36 08 a7 0d 04 00 01 13 02 35 78 35 0e 0e 5x6........5x5.. | 3664: b3 00 08 00 01 00 03 08 a7 0b 04 00 01 13 02 35 ...............5 | 3680: 78 33 0e d1 00 08 a7 09 04 00 01 13 02 35 78 31 x3...........5x1 | 3696: 09 9f 2a 04 00 01 15 02 34 78 31 30 03 cf 29 04 ..*.....4x10..). | 3712: 00 01 13 02 34 78 39 08 9f 28 04 00 01 13 02 34 ....4x9..(.....4 | 3728: 78 38 09 9f 27 04 00 01 13 02 34 78 37 08 9f 26 x8..'.....4x7..& | 3744: 04 00 01 13 0e a4 78 36 08 9f 25 04 00 01 13 02 ......x6..%..... | 3760: 34 78 35 0f 18 00 09 00 09 13 34 78 08 9f 23 04 4x5.......4x..#. | 3776: 00 01 13 02 34 78 33 0f 36 00 08 9f 21 04 00 01 ....4x3.6...!... | 3792: 13 02 34 78 31 09 97 42 04 00 01 15 02 33 78 31 ..4x1..B.....3x1 | 3808: 30 08 97 41 04 00 01 13 02 33 78 39 08 97 40 04 0..A.....3x9..@. | 3824: 00 01 13 02 33 78 38 18 97 3f 04 00 01 13 02 33 ....3x8..?.....3 | 3840: 78 37 08 97 3e 04 00 01 13 02 33 78 36 08 97 3d x7..>.....3x6..= | 3856: 04 00 01 13 02 33 78 35 1f 7d 00 09 00 09 13 33 .....3x5.......3 | 3872: 78 07 97 3b 04 00 01 13 02 33 78 33 0f 9b 00 08 x..;.....3x3.... | 3888: 97 39 04 00 01 13 02 33 78 31 09 8f 5a 04 00 01 .9.....3x1..Z... | 3904: 15 02 32 79 31 30 08 8f 59 04 00 01 13 fa 32 78 ..2y10..Y.....2x | 3920: 39 08 8f 58 04 00 01 13 02 32 78 38 08 8f 57 04 9..X.....2x8..W. | 3936: 00 01 13 02 32 78 37 08 8f 56 04 00 01 13 02 32 ....2x7..V.....2 | 3952: 78 36 08 8f 55 04 00 01 13 02 32 78 35 0f e2 00 x6..U.....2x5... | 3968: 09 00 09 13 32 78 08 8f 53 04 00 01 13 02 32 78 ....2x..S.....2x | 3984: 33 00 00 00 08 8f 51 04 00 01 13 02 aa 78 31 09 3.....Q......x1. | 4000: 87 72 04 00 01 15 02 31 78 31 30 08 87 71 04 00 .r.....1x10..q.. | 4016: 01 13 03 31 78 39 08 87 70 04 00 01 13 02 31 78 ...1x9..p.....1x | 4032: 38 08 87 6f 04 00 01 13 02 31 78 37 08 87 6e 04 8..o.....1x7..n. | 4048: 00 01 13 02 31 78 36 08 87 6d 04 00 01 13 02 31 ....1x6..m.....1 | 4064: 7d 25 0f f9 00 08 ff f9 13 31 78 08 87 6b 04 00 .%.......1x..k.. | 4080: 01 13 02 31 78 33 00 00 00 00 00 08 00 01 00 03 ...1x3.......... | page 4 offset 12288 | 0: 0d 00 00 00 03 01 87 00 0b 2d 06 5a 01 87 00 00 .........-.Z.... | 384: 00 00 00 00 00 00 00 89 50 01 54 00 93 24 00 00 ........P.T..$.. | 400: 00 32 00 00 00 00 00 00 23 2f 00 00 00 09 00 00 .2......#/...... | 416: 00 0b 00 00 00 07 00 00 00 09 00 00 00 00 00 00 ................ | 432: 23 2e 00 00 10 09 00 00 00 0b 00 00 00 06 00 00 #............... | 448: 00 08 00 00 00 00 00 00 23 2d 00 00 00 09 00 00 ........#-...... | 464: 00 0b 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................ | 480: 23 2c 00 00 00 09 00 00 00 0b 00 00 00 04 00 00 #,.............. | 496: 00 06 00 00 00 00 00 00 23 2b 00 00 00 09 00 00 ........#+...... | 512: 00 0b 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................ | 528: 23 2a 00 00 00 09 00 00 00 0b 00 00 00 02 00 00 #*.............. | 544: 00 04 00 00 00 00 00 00 23 29 00 00 00 09 00 00 ........#)...... | 560: 00 0b 00 00 00 01 00 00 00 03 00 00 00 00 00 00 ................ | 576: 1f 4a 00 00 00 08 00 00 00 0a 00 00 00 0a 00 00 .J.............. | 592: 00 0c 00 00 00 00 00 00 0f 49 00 00 00 08 00 00 .........I...... | 608: 00 0a 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................ | 624: 1f 48 00 00 00 08 00 00 00 0a 00 00 00 08 00 06 .H.............. | 640: 00 0a 00 00 00 00 00 00 1f 47 00 00 00 08 00 00 .........G...... | 656: 00 0a 00 00 00 07 00 00 00 09 00 00 00 00 00 00 ................ | 672: 15 d6 00 00 00 08 00 00 00 0a 00 00 00 06 00 00 ................ | 688: 00 08 00 00 00 00 00 00 1f 45 00 00 00 08 00 00 .........E...... | 704: 00 0a 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................ | 720: 1f 44 00 00 00 08 00 00 00 0a 00 00 00 04 00 00 .D.............. | 736: 00 06 00 00 00 00 00 00 1f 43 00 00 00 07 ff ff .........C...... | 752: f0 0a 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................ | 768: 1f 42 00 00 00 08 00 00 00 0a 00 00 00 01 ff f0 .B.............. | 784: 00 03 ff ff ff ff ff ff 1f 41 00 00 00 08 00 00 .........A...... | 800: 00 0a 00 00 00 01 00 00 00 03 00 00 00 00 00 00 ................ | 816: 1b 62 00 00 00 07 00 00 00 09 00 00 00 0a 00 00 .b.............. | 832: 00 0c 05 00 00 00 00 00 1b 64 10 00 00 07 00 00 .........d...... | 848: 00 09 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................ | 864: 1b 60 00 00 00 07 00 00 00 09 00 00 00 08 00 00 .`.............. | 880: 00 0a 00 00 00 00 00 00 1b 5f 00 00 00 07 00 00 ........._...... | 896: 00 09 00 00 00 07 00 00 00 09 00 00 00 00 00 00 ................ | 912: 1b 5e 00 00 00 07 00 00 00 09 00 00 00 06 00 00 .^.............. | 928: 00 08 00 00 00 00 00 00 1b 5d 00 00 00 08 00 00 .........]...... | 944: 00 09 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................ | 960: 1b 5c 00 00 00 07 00 00 00 09 00 00 00 04 00 00 ................ | 976: 06 46 00 00 00 00 00 00 1b 5b 00 00 00 07 00 00 .F.......[...... | 992: 00 09 00 00 00 03 00 00 00 04 ff f0 00 00 00 00 ................ | 1008: 1b 5a 00 00 00 07 00 00 00 19 00 00 00 02 00 00 .Z.............. | 1024: 00 04 00 00 00 00 00 00 1b 59 00 00 00 07 00 00 .........Y...... | 1040: 00 09 00 00 00 01 00 00 00 03 00 00 00 00 ff f0 ................ | 1056: 17 7a 00 00 00 06 00 00 00 08 00 00 00 0a 00 00 .z.............. | 1072: 00 0c 00 00 00 00 00 00 17 79 00 00 00 06 00 00 .........y...... | 1088: 00 08 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................ | 1104: 17 78 00 00 00 06 00 00 00 08 00 00 00 08 00 00 .x.............. | 1120: 00 0a 00 00 00 00 00 00 17 77 00 00 00 06 10 00 .........w...... | 1136: 00 08 00 00 00 07 00 09 c0 09 00 00 00 00 00 00 ................ | 1152: 17 76 00 00 00 06 00 00 00 08 00 00 00 06 00 00 .v.............. | 1168: 00 08 00 00 00 00 00 00 17 75 00 00 00 06 00 00 .........u...... | 1184: 00 08 00 00 00 05 00 00 00 07 00 00 00 00 00 00 ................ | 1200: 17 74 00 00 00 06 00 00 00 08 00 00 00 03 ff ff .t.............. | 1216: f0 06 00 00 00 83 00 00 17 73 00 00 00 06 00 00 .........s...... | 1232: 00 08 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................ | 1248: 17 71 ff 00 00 06 00 00 10 08 00 00 00 02 00 00 .q.............. | 1264: 00 04 00 00 c0 00 00 00 17 0d 00 00 00 06 00 00 ................ | 1280: 00 08 00 00 e7 01 00 00 00 03 00 00 09 e0 00 00 ................ | 1296: 23 30 00 00 00 09 00 00 00 0a 00 00 00 08 00 00 #0.............. | 1312: 00 0a 00 00 00 00 bb 00 23 31 00 00 00 09 00 00 ........#1...... | 1328: 00 0b 00 00 00 09 00 00 00 0b 00 00 00 00 00 00 ................ | 1344: 23 32 00 00 00 09 00 00 00 0b 00 00 00 0a 00 00 #2.............. | 1360: 00 0c 00 00 00 00 00 00 27 11 00 00 00 0a 00 00 ........'....... | 1376: 00 0c 00 00 00 01 00 08 c0 03 00 00 00 00 00 00 ................ | 1392: 27 12 00 00 00 0a 00 00 00 0c 51 00 00 02 00 00 '.........Q..... | 1408: 00 04 6f 00 00 00 00 00 27 13 00 00 00 09 ff ff ..o.....'....... | 1424: 00 0c 00 00 00 03 00 00 00 05 00 00 00 00 00 00 ................ | 1440: 27 14 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 '............... | 1616: 00 00 00 00 00 00 00 00 00 00 89 50 02 04 00 93 ...........P.... | 1632: 24 00 00 00 32 00 00 00 00 00 00 23 8c 00 00 00 $...2......#.... | 1648: 05 00 00 00 07 00 00 00 04 00 00 00 06 00 00 00 ................ | 1664: 00 00 00 0f a4 00 00 00 04 00 00 00 06 00 00 00 ................ | 1680: 04 00 00 00 06 00 00 00 00 00 00 0b bc 00 00 00 ................ | 1696: 03 00 00 00 05 00 00 00 04 00 00 00 06 00 00 00 ................ | 1712: 00 00 00 07 d4 00 00 00 02 00 00 00 04 00 00 00 ................ | 1728: 04 00 00 00 06 00 00 00 10 00 00 03 ec 00 00 00 ................ | 1744: 01 00 00 00 03 00 00 00 04 00 00 00 06 00 00 00 ................ | 1760: 00 00 00 13 8d 00 00 00 05 00 00 00 07 00 00 00 ................ | 1776: 05 00 00 00 07 00 00 00 00 00 00 0f a5 00 00 00 ................ | 1792: 04 00 00 00 06 00 00 00 05 00 00 00 07 00 00 00 ................ | 1808: 00 00 00 0b bd 00 00 00 03 00 00 00 05 00 00 00 ................ | 1824: 05 00 00 00 07 00 00 00 00 00 00 07 d5 00 00 00 ................ | 1840: 02 00 00 00 05 00 00 00 05 00 00 00 07 00 00 00 ................ | 1856: 00 00 00 03 ed 00 00 00 01 00 00 00 03 00 00 00 ................ | 1872: 05 00 00 00 07 00 00 00 00 00 00 13 8e 00 00 00 ................ | 1888: 05 00 00 00 07 00 00 00 06 00 00 00 08 00 00 00 ................ | 1904: 00 00 00 0f a6 00 00 00 04 00 00 00 06 00 00 00 ................ | 1920: 06 00 00 00 07 ff ff 00 00 00 00 0b be 00 00 00 ................ | 1936: 0b 40 00 00 05 00 00 00 06 00 00 00 08 00 00 00 .@.............. | 1952: 00 00 00 07 d6 00 00 00 02 00 00 00 04 00 00 00 ................ | 1968: 05 00 00 00 08 00 00 00 00 00 00 03 ee 00 00 00 ................ | 1984: 01 00 00 00 02 ff ff 00 06 00 00 00 08 00 00 00 ................ | 2000: 00 00 00 13 8f 00 00 00 05 00 00 00 07 00 00 00 ................ | 2016: 07 00 00 00 09 00 00 00 00 00 00 0f a7 00 00 00 ................ | 2032: 04 00 00 00 06 00 00 00 07 00 00 00 09 00 00 08 ................ | 2048: 30 00 00 0b bf 00 00 00 03 00 00 00 05 00 00 00 0............... | 2064: 07 00 00 00 09 00 00 00 00 00 00 07 d7 00 00 00 ................ | 2080: 02 00 00 00 04 00 00 00 07 00 00 00 09 00 00 00 ................ | 2096: 00 00 00 03 ef 00 00 00 01 00 00 00 03 00 00 00 ................ | 2112: 07 00 00 00 09 00 00 00 00 00 00 13 90 00 00 00 ................ | 2128: 05 00 01 00 07 00 00 00 08 00 00 00 0a 00 00 00 ................ | 2144: 00 00 00 0f a8 00 00 00 04 00 00 00 06 00 00 00 ................ | 2160: 08 00 00 00 0a 00 00 00 00 00 00 0b f2 00 00 00 ................ | 2176: 03 00 00 00 05 00 00 00 08 00 00 00 0a 00 00 01 ................ | 2192: 00 00 00 07 d8 00 00 00 02 00 00 00 04 00 00 00 ................ | 2208: 08 00 00 00 0a 00 00 00 00 00 00 03 f0 00 00 00 ................ | 2224: 01 00 00 00 03 00 00 00 08 00 00 00 09 ff 00 00 ................ | 2240: 00 00 00 13 91 00 00 00 05 00 00 00 07 00 00 00 ................ | 2256: 09 00 00 00 0b 00 00 00 00 00 00 0f a9 00 00 00 ................ | 2272: 04 00 00 00 06 00 00 00 09 00 00 00 0b 00 00 00 ................ | 2288: 00 00 00 0b c1 00 00 00 03 00 00 00 05 00 00 00 ................ | 2304: 09 00 00 00 0b 00 00 00 00 00 00 07 d9 00 00 00 ................ | 2320: 02 00 00 00 04 00 00 00 09 00 00 00 0b 00 00 01 ................ | 2336: 00 00 00 03 f0 ff ff 00 01 00 00 00 03 00 00 00 ................ | 2352: 09 00 00 00 0b 00 00 00 00 00 00 13 92 00 00 00 ................ | 2368: 05 00 00 00 07 00 00 00 0a 00 00 00 0c 00 00 00 ................ | 2384: 00 00 00 0f aa 00 00 00 04 00 00 00 06 00 00 00 ................ | 2400: 0a 00 00 00 0c 00 00 00 00 00 00 0b c2 00 00 00 ................ | 2416: 03 00 00 00 05 00 00 00 0a 00 00 00 0c 00 00 00 ................ | 2432: 00 00 00 07 da 00 00 00 02 00 00 00 04 00 00 00 ................ | 2448: 0a 00 00 00 0c 00 00 00 00 00 00 03 f2 00 00 00 ................ | 2464: 01 00 00 10 03 00 00 00 0a 00 00 00 0c 00 00 00 ................ | 2480: 00 00 00 03 eb 00 00 00 01 00 00 00 03 00 00 00 ................ | 2496: 03 00 00 00 05 00 00 00 00 00 00 07 d3 00 00 00 ................ | 2512: 02 00 00 00 04 00 00 00 03 00 00 00 05 00 00 00 ................ | 2528: 00 00 00 0b bb 00 00 00 03 00 00 00 05 00 00 00 ................ | 2544: 03 00 00 00 05 00 00 00 00 00 00 0f a3 00 00 00 ................ | 2560: 04 00 00 00 06 00 00 00 03 00 00 00 05 00 00 00 ................ | 2576: 00 00 00 13 8b 00 00 00 05 00 00 00 07 00 00 00 ................ | 2592: 03 00 00 00 05 00 00 00 00 00 00 03 ea 00 00 00 ................ | 2608: 01 00 00 00 03 00 00 00 02 00 00 00 04 00 00 00 ................ | 2624: 00 00 00 07 d2 00 00 00 02 00 00 00 04 00 00 00 ................ | 2640: 02 00 00 00 04 00 00 00 00 00 00 0b ba 00 00 00 ................ | 2656: 03 00 00 00 05 00 00 00 02 00 00 00 04 00 00 00 ................ | 2672: 00 00 00 0f a1 ff ff ff 04 00 00 00 06 00 00 00 ................ | 2688: 02 00 00 00 04 00 00 00 00 00 00 13 8a 00 00 00 ................ | 2704: 05 00 00 00 06 ff ff ff f2 00 00 00 04 00 00 00 ................ | 2720: 00 00 00 03 e9 00 00 00 01 00 00 00 03 00 00 00 ................ | 2736: 01 00 00 00 03 00 00 00 00 00 00 07 d1 00 00 00 ................ | 2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01 ..............P. | 2864: 04 00 93 24 00 01 00 02 00 00 00 00 00 00 00 02 ...$............ | 2880: ff ff ff 06 00 00 00 0c 00 00 00 01 00 00 00 0b ................ | 2896: 00 00 00 00 00 00 00 02 40 00 00 00 00 00 00 00 ........@....... | end crash-2e81f5dce5cbd4.db}] execsql { PRAGMA writable_schema = 1;} catchsql {UPDATE t1 SET ex= ex ISNULL} } {1 {database disk image is malformed}} finish_test |
Changes to ext/session/sqlite3session.c.
︙ | ︙ | |||
1840 1841 1842 1843 1844 1845 1846 | */ static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){ if( *pRc==SQLITE_OK && (size_t)(p->nAlloc-p->nBuf)<nByte ){ u8 *aNew; i64 nNew = p->nAlloc ? p->nAlloc : 128; do { nNew = nNew*2; | | | 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 | */ static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){ if( *pRc==SQLITE_OK && (size_t)(p->nAlloc-p->nBuf)<nByte ){ u8 *aNew; i64 nNew = p->nAlloc ? p->nAlloc : 128; do { nNew = nNew*2; }while( (size_t)(nNew-p->nBuf)<nByte ); aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew); if( 0==aNew ){ *pRc = SQLITE_NOMEM; }else{ p->aBuf = aNew; p->nAlloc = nNew; |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
524 525 526 527 528 529 530 | 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 | < | 524 525 526 527 528 529 530 531 532 533 534 535 536 537 | 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 FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000 FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000 FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4 FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE |
︙ | ︙ |
Changes to src/alter.c.
︙ | ︙ | |||
132 133 134 135 136 137 138 | /* Make sure it is not a system table being altered, or a reserved name ** that the table is being renamed to. */ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ goto exit_rename_table; } | | | | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | /* Make sure it is not a system table being altered, or a reserved name ** that the table is being renamed to. */ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ goto exit_rename_table; } if( SQLITE_OK!=sqlite3CheckObjectName(pParse,zName,"table",zName) ){ goto exit_rename_table; } #ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName); goto exit_rename_table; } |
︙ | ︙ |
Changes to src/analyze.c.
︙ | ︙ | |||
23 24 25 26 27 28 29 | ** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample); ** ** Additional tables might be added in future releases of SQLite. ** The sqlite_stat2 table is not created or used unless the SQLite version ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled ** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. ** The sqlite_stat2 table is superseded by sqlite_stat3, which is only | | | | | | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | ** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample); ** ** Additional tables might be added in future releases of SQLite. ** The sqlite_stat2 table is not created or used unless the SQLite version ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled ** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. ** The sqlite_stat2 table is superseded by sqlite_stat3, which is only ** created and used by SQLite versions 3.7.9 through 3.29.0 when ** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 ** is a superset of sqlite_stat2 and is also now deprecated. The ** sqlite_stat4 is an enhanced version of sqlite_stat3 and is only ** available when compiled with SQLITE_ENABLE_STAT4 and in SQLite ** versions 3.8.1 and later. STAT4 is the only variant that is still ** supported. ** ** For most applications, sqlite_stat1 provides all the statistics required ** for the query planner to make good choices. ** ** Format of sqlite_stat1: ** ** There is normally one row per index, with the index identified by the |
︙ | ︙ | |||
140 141 142 143 144 145 146 | ** integer in the equivalent columns in sqlite_stat4. */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" #if defined(SQLITE_ENABLE_STAT4) # define IsStat4 1 | < < < < < < | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | ** integer in the equivalent columns in sqlite_stat4. */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" #if defined(SQLITE_ENABLE_STAT4) # define IsStat4 1 #else # define IsStat4 0 # undef SQLITE_STAT4_SAMPLES # define SQLITE_STAT4_SAMPLES 1 #endif /* ** This routine generates code that opens the sqlite_statN tables. ** The sqlite_stat1 table is always relevant. sqlite_stat2 is now ** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when ** appropriate compile-time options are provided. ** |
︙ | ︙ | |||
179 180 181 182 183 184 185 | static const struct { const char *zName; const char *zCols; } aTable[] = { { "sqlite_stat1", "tbl,idx,stat" }, #if defined(SQLITE_ENABLE_STAT4) { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" }, | < < < < < > | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | static const struct { const char *zName; const char *zCols; } aTable[] = { { "sqlite_stat1", "tbl,idx,stat" }, #if defined(SQLITE_ENABLE_STAT4) { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" }, #else { "sqlite_stat4", 0 }, #endif { "sqlite_stat3", 0 }, }; int i; sqlite3 *db = pParse->db; Db *pDb; Vdbe *v = sqlite3GetVdbe(pParse); int aRoot[ArraySize(aTable)]; u8 aCreateTbl[ArraySize(aTable)]; |
︙ | ︙ | |||
267 268 269 270 271 272 273 | ** information. */ typedef struct Stat4Accum Stat4Accum; typedef struct Stat4Sample Stat4Sample; struct Stat4Sample { tRowcnt *anEq; /* sqlite_stat4.nEq */ tRowcnt *anDLt; /* sqlite_stat4.nDLt */ | | | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | ** information. */ typedef struct Stat4Accum Stat4Accum; typedef struct Stat4Sample Stat4Sample; struct Stat4Sample { tRowcnt *anEq; /* sqlite_stat4.nEq */ tRowcnt *anDLt; /* sqlite_stat4.nDLt */ #ifdef SQLITE_ENABLE_STAT4 tRowcnt *anLt; /* sqlite_stat4.nLt */ union { i64 iRowid; /* Rowid in main table of the key */ u8 *aRowid; /* Key for WITHOUT ROWID tables */ } u; u32 nRowid; /* Sizeof aRowid[] */ u8 isPSample; /* True if a periodic sample */ |
︙ | ︙ | |||
298 299 300 301 302 303 304 | int iGet; /* Index of current sample accessed by stat_get() */ Stat4Sample *a; /* Array of mxSample Stat4Sample objects */ sqlite3 *db; /* Database connection, for malloc() */ }; /* Reclaim memory used by a Stat4Sample */ | | | | | | | | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | int iGet; /* Index of current sample accessed by stat_get() */ Stat4Sample *a; /* Array of mxSample Stat4Sample objects */ sqlite3 *db; /* Database connection, for malloc() */ }; /* Reclaim memory used by a Stat4Sample */ #ifdef SQLITE_ENABLE_STAT4 static void sampleClear(sqlite3 *db, Stat4Sample *p){ assert( db!=0 ); if( p->nRowid ){ sqlite3DbFree(db, p->u.aRowid); p->nRowid = 0; } } #endif /* Initialize the BLOB value of a ROWID */ #ifdef SQLITE_ENABLE_STAT4 static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){ assert( db!=0 ); if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); p->u.aRowid = sqlite3DbMallocRawNN(db, n); if( p->u.aRowid ){ p->nRowid = n; memcpy(p->u.aRowid, pData, n); }else{ p->nRowid = 0; } } #endif /* Initialize the INTEGER value of a ROWID. */ #ifdef SQLITE_ENABLE_STAT4 static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){ assert( db!=0 ); if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); p->nRowid = 0; p->u.iRowid = iRowid; } #endif /* ** Copy the contents of object (*pFrom) into (*pTo). */ #ifdef SQLITE_ENABLE_STAT4 static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){ pTo->isPSample = pFrom->isPSample; pTo->iCol = pFrom->iCol; pTo->iHash = pFrom->iHash; memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol); memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol); memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol); if( pFrom->nRowid ){ sampleSetRowid(p->db, pTo, pFrom->nRowid, pFrom->u.aRowid); }else{ sampleSetRowidInt64(p->db, pTo, pFrom->u.iRowid); } } #endif /* ** Reclaim all memory of a Stat4Accum structure. */ static void stat4Destructor(void *pOld){ Stat4Accum *p = (Stat4Accum*)pOld; #ifdef SQLITE_ENABLE_STAT4 int i; for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i); for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i); sampleClear(p->db, &p->current); #endif sqlite3DbFree(p->db, p); } /* ** Implementation of the stat_init(N,K,C) SQL function. The three parameters ** are: ** N: The number of columns in the index including the rowid/pk (note 1) ** K: The number of columns in the index excluding the rowid/pk. ** C: The number of rows in the index (note 2) ** ** Note 1: In the special case of the covering index that implements a ** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the ** total number of columns in the table. ** ** Note 2: C is only used for STAT4. ** ** For indexes on ordinary rowid tables, N==K+1. But for indexes on ** WITHOUT ROWID tables, N=K+P where P is the number of columns in the ** PRIMARY KEY of the table. The covering index that implements the ** original WITHOUT ROWID table as N==K as a special case. ** ** This routine allocates the Stat4Accum object in heap memory. The return |
︙ | ︙ | |||
403 404 405 406 407 408 409 | ){ Stat4Accum *p; int nCol; /* Number of columns in index being sampled */ int nKeyCol; /* Number of key columns */ int nColUp; /* nCol rounded up for alignment */ int n; /* Bytes of space to allocate */ sqlite3 *db; /* Database connection */ | | | | | 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | ){ Stat4Accum *p; int nCol; /* Number of columns in index being sampled */ int nKeyCol; /* Number of key columns */ int nColUp; /* nCol rounded up for alignment */ int n; /* Bytes of space to allocate */ sqlite3 *db; /* Database connection */ #ifdef SQLITE_ENABLE_STAT4 int mxSample = SQLITE_STAT4_SAMPLES; #endif /* Decode the three function arguments */ UNUSED_PARAMETER(argc); nCol = sqlite3_value_int(argv[0]); assert( nCol>0 ); nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol; nKeyCol = sqlite3_value_int(argv[1]); assert( nKeyCol<=nCol ); assert( nKeyCol>0 ); /* Allocate the space required for the Stat4Accum object */ n = sizeof(*p) + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */ #ifdef SQLITE_ENABLE_STAT4 + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */ + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */ + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample) #endif ; db = sqlite3_context_db_handle(context); p = sqlite3DbMallocZero(db, n); if( p==0 ){ sqlite3_result_error_nomem(context); return; } p->db = db; p->nRow = 0; p->nCol = nCol; p->nKeyCol = nKeyCol; p->current.anDLt = (tRowcnt*)&p[1]; p->current.anEq = &p->current.anDLt[nColUp]; #ifdef SQLITE_ENABLE_STAT4 { u8 *pSpace; /* Allocated space not yet assigned */ int i; /* Used to iterate through p->aSample[] */ p->iGet = -1; p->mxSample = mxSample; p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1); |
︙ | ︙ | |||
475 476 477 478 479 480 481 | /* Return a pointer to the allocated object to the caller. Note that ** only the pointer (the 2nd parameter) matters. The size of the object ** (given by the 3rd parameter) is never used and can be any positive ** value. */ sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor); } static const FuncDef statInitFuncdef = { | | | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | /* Return a pointer to the allocated object to the caller. Note that ** only the pointer (the 2nd parameter) matters. The size of the object ** (given by the 3rd parameter) is never used and can be any positive ** value. */ sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor); } static const FuncDef statInitFuncdef = { 2+IsStat4, /* nArg */ SQLITE_UTF8, /* funcFlags */ 0, /* pUserData */ 0, /* pNext */ statInit, /* xSFunc */ 0, /* xFinalize */ 0, 0, /* xValue, xInverse */ "stat_init", /* zName */ |
︙ | ︙ | |||
515 516 517 518 519 520 521 | if( pNew->anEq[i]<pOld->anEq[i] ) return 0; } if( pNew->iHash>pOld->iHash ) return 1; return 0; } #endif | | < < < < < | 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | if( pNew->anEq[i]<pOld->anEq[i] ) return 0; } if( pNew->iHash>pOld->iHash ) return 1; return 0; } #endif #ifdef SQLITE_ENABLE_STAT4 /* ** Return true if pNew is to be preferred over pOld. ** ** This function assumes that for each argument sample, the contents of ** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. */ static int sampleIsBetter( Stat4Accum *pAccum, Stat4Sample *pNew, Stat4Sample *pOld ){ tRowcnt nEqNew = pNew->anEq[pNew->iCol]; tRowcnt nEqOld = pOld->anEq[pOld->iCol]; assert( pOld->isPSample==0 && pNew->isPSample==0 ); assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); if( (nEqNew>nEqOld) ) return 1; if( nEqNew==nEqOld ){ if( pNew->iCol<pOld->iCol ) return 1; return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld)); } return 0; } /* ** Copy the contents of sample *pNew into the p->a[] array. If necessary, ** remove the least desirable sample from p->a[] to make room. */ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ Stat4Sample *pSample = 0; int i; assert( IsStat4 || nEqZero==0 ); /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0 ** values in the anEq[] array of any sample in Stat4Accum.a[]. In ** other words, if nMaxEqZero is n, then it is guaranteed that there ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */ if( nEqZero>p->nMaxEqZero ){ p->nMaxEqZero = nEqZero; } |
︙ | ︙ | |||
589 590 591 592 593 594 595 | } if( pUpgrade ){ pUpgrade->iCol = pNew->iCol; pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol]; goto find_new_min; } } | < < < < | < | | 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 | } if( pUpgrade ){ pUpgrade->iCol = pNew->iCol; pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol]; goto find_new_min; } } /* If necessary, remove sample iMin to make room for the new sample. */ if( p->nSample>=p->mxSample ){ Stat4Sample *pMin = &p->a[p->iMin]; tRowcnt *anEq = pMin->anEq; tRowcnt *anLt = pMin->anLt; tRowcnt *anDLt = pMin->anDLt; sampleClear(p->db, pMin); memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1)); pSample = &p->a[p->nSample-1]; pSample->nRowid = 0; pSample->anEq = anEq; pSample->anDLt = anDLt; pSample->anLt = anLt; p->nSample = p->mxSample-1; } /* The "rows less-than" for the rowid column must be greater than that ** for the last sample in the p->a[] array. Otherwise, the samples would ** be out of order. */ assert( p->nSample==0 || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] ); /* Insert the new sample */ pSample = &p->a[p->nSample]; sampleCopy(p, pSample, pNew); p->nSample++; /* Zero the first nEqZero entries in the anEq[] array. */ memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); find_new_min: if( p->nSample>=p->mxSample ){ int iMin = -1; for(i=0; i<p->mxSample; i++){ if( p->a[i].isPSample ) continue; if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){ iMin = i; } } assert( iMin>=0 ); p->iMin = iMin; } } #endif /* SQLITE_ENABLE_STAT4 */ /* ** Field iChng of the index being scanned has changed. So at this point ** p->current contains a sample that reflects the previous row of the ** index. The value of anEq[iChng] and subsequent anEq[] elements are ** correct at this point. */ |
︙ | ︙ | |||
679 680 681 682 683 684 685 | if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; } } p->nMaxEqZero = iChng; } #endif | < < < < < < < < < < < < < < < < < < < < < | | | 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 | if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; } } p->nMaxEqZero = iChng; } #endif #ifndef SQLITE_ENABLE_STAT4 UNUSED_PARAMETER( p ); UNUSED_PARAMETER( iChng ); #endif } /* ** Implementation of the stat_push SQL function: stat_push(P,C,R) ** Arguments: ** ** P Pointer to the Stat4Accum object created by stat_init() ** C Index of left-most column to differ from previous row ** R Rowid for the current row. Might be a key record for ** WITHOUT ROWID tables. ** ** This SQL function always returns NULL. It's purpose it to accumulate ** statistical data and/or samples in the Stat4Accum object about the ** index being analyzed. The stat_get() SQL function will later be used to ** extract relevant information for constructing the sqlite_statN tables. ** ** The R parameter is only used for STAT4 */ static void statPush( sqlite3_context *context, int argc, sqlite3_value **argv ){ int i; |
︙ | ︙ | |||
752 753 754 755 756 757 758 | /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply ** to the current row of the index. */ for(i=0; i<iChng; i++){ p->current.anEq[i]++; } for(i=iChng; i<p->nCol; i++){ p->current.anDLt[i]++; | | | | 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 | /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply ** to the current row of the index. */ for(i=0; i<iChng; i++){ p->current.anEq[i]++; } for(i=iChng; i<p->nCol; i++){ p->current.anDLt[i]++; #ifdef SQLITE_ENABLE_STAT4 p->current.anLt[i] += p->current.anEq[i]; #endif p->current.anEq[i] = 1; } } p->nRow++; #ifdef SQLITE_ENABLE_STAT4 if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){ sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2])); }else{ sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]), sqlite3_value_blob(argv[2])); } p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345; |
︙ | ︙ | |||
792 793 794 795 796 797 798 | sampleCopy(p, &p->aBest[i], &p->current); } } } #endif } static const FuncDef statPushFuncdef = { | | | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | sampleCopy(p, &p->aBest[i], &p->current); } } } #endif } static const FuncDef statPushFuncdef = { 2+IsStat4, /* nArg */ SQLITE_UTF8, /* funcFlags */ 0, /* pUserData */ 0, /* pNext */ statPush, /* xSFunc */ 0, /* xFinalize */ 0, 0, /* xValue, xInverse */ "stat_push", /* zName */ |
︙ | ︙ | |||
823 824 825 826 827 828 829 | ** ** The stat_get(P,J) function is not available to generic SQL. It is ** inserted as part of a manually constructed bytecode program. (See ** the callStatGet() routine below.) It is guaranteed that the P ** parameter will always be a poiner to a Stat4Accum object, never a ** NULL. ** | | | | | 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 | ** ** The stat_get(P,J) function is not available to generic SQL. It is ** inserted as part of a manually constructed bytecode program. (See ** the callStatGet() routine below.) It is guaranteed that the P ** parameter will always be a poiner to a Stat4Accum object, never a ** NULL. ** ** If STAT4 is not enabled, then J is always ** STAT_GET_STAT1 and is hence omitted and this routine becomes ** a one-parameter function, stat_get(P), that always returns the ** stat1 table entry information. */ static void statGet( sqlite3_context *context, int argc, sqlite3_value **argv ){ Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); #ifdef SQLITE_ENABLE_STAT4 /* STAT4 has a parameter on this routine. */ int eCall = sqlite3_value_int(argv[1]); assert( argc==2 ); assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT || eCall==STAT_GET_NDLT ); if( eCall==STAT_GET_STAT1 ) |
︙ | ︙ | |||
890 891 892 893 894 895 896 | z += sqlite3Strlen30(z); assert( p->current.anEq[i] ); } assert( z[0]=='\0' && z>zRet ); sqlite3_result_text(context, zRet, -1, sqlite3_free); } | | | 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 | z += sqlite3Strlen30(z); assert( p->current.anEq[i] ); } assert( z[0]=='\0' && z>zRet ); sqlite3_result_text(context, zRet, -1, sqlite3_free); } #ifdef SQLITE_ENABLE_STAT4 else if( eCall==STAT_GET_ROWID ){ if( p->iGet<0 ){ samplePushPrevious(p, 0); p->iGet = 0; } if( p->iGet<p->nSample ){ Stat4Sample *pS = p->a + p->iGet; |
︙ | ︙ | |||
919 920 921 922 923 924 925 | default: { aCnt = p->a[p->iGet].anDLt; p->iGet++; break; } } | < < < > | | | | | 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 | default: { aCnt = p->a[p->iGet].anDLt; p->iGet++; break; } } { char *zRet = sqlite3MallocZero(p->nCol * 25); if( zRet==0 ){ sqlite3_result_error_nomem(context); }else{ int i; char *z = zRet; for(i=0; i<p->nCol; i++){ sqlite3_snprintf(24, z, "%llu ", (u64)aCnt[i]); z += sqlite3Strlen30(z); } assert( z[0]=='\0' && z>zRet ); z[-1] = '\0'; sqlite3_result_text(context, zRet, -1, sqlite3_free); } } } #endif /* SQLITE_ENABLE_STAT4 */ #ifndef SQLITE_DEBUG UNUSED_PARAMETER( argc ); #endif } static const FuncDef statGetFuncdef = { 1+IsStat4, /* nArg */ SQLITE_UTF8, /* funcFlags */ 0, /* pUserData */ 0, /* pNext */ statGet, /* xSFunc */ 0, /* xFinalize */ 0, 0, /* xValue, xInverse */ "stat_get", /* zName */ {0} }; static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ assert( regOut!=regStat4 && regOut!=regStat4+1 ); #ifdef SQLITE_ENABLE_STAT4 sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1); #elif SQLITE_DEBUG assert( iParam==STAT_GET_STAT1 ); #else UNUSED_PARAMETER( iParam ); #endif sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut, (char*)&statGetFuncdef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, 1 + IsStat4); } /* ** Generate code to do an analysis of all indices associated with ** a single table. */ static void analyzeOneTable( |
︙ | ︙ | |||
993 994 995 996 997 998 999 | int i; /* Loop counter */ int jZeroRows = -1; /* Jump from here if number of rows is zero */ int iDb; /* Index of database containing pTab */ u8 needTableCnt = 1; /* True to count the table */ int regNewRowid = iMem++; /* Rowid for the inserted record */ int regStat4 = iMem++; /* Register to hold Stat4Accum object */ int regChng = iMem++; /* Index of changed index field */ | | | 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 | int i; /* Loop counter */ int jZeroRows = -1; /* Jump from here if number of rows is zero */ int iDb; /* Index of database containing pTab */ u8 needTableCnt = 1; /* True to count the table */ int regNewRowid = iMem++; /* Rowid for the inserted record */ int regStat4 = iMem++; /* Register to hold Stat4Accum object */ int regChng = iMem++; /* Index of changed index field */ #ifdef SQLITE_ENABLE_STAT4 int regRowid = iMem++; /* Rowid argument passed to stat_push() */ #endif int regTemp = iMem++; /* Temporary use register */ int regTabname = iMem++; /* Register containing table name */ int regIdxname = iMem++; /* Register containing index name */ int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ int regPrev = iMem; /* MUST BE LAST (see below) */ |
︙ | ︙ | |||
1127 1128 1129 1130 1131 1132 1133 | ** ** (1) the number of columns in the index including the rowid ** (or for a WITHOUT ROWID table, the number of PK columns), ** (2) the number of columns in the key without the rowid/pk ** (3) the number of rows in the index, ** ** | | | | | 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 | ** ** (1) the number of columns in the index including the rowid ** (or for a WITHOUT ROWID table, the number of PK columns), ** (2) the number of columns in the key without the rowid/pk ** (3) the number of rows in the index, ** ** ** The third argument is only used for STAT4 */ #ifdef SQLITE_ENABLE_STAT4 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); #endif sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2); sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4, (char*)&statInitFuncdef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, 2+IsStat4); /* Implementation of the following: ** ** Rewind csr ** if eof(csr) goto end_of_scan; ** regChng = 0 ** goto next_push_0; |
︙ | ︙ | |||
1207 1208 1209 1210 1211 1212 1213 | } sqlite3VdbeResolveLabel(v, endDistinctTest); sqlite3DbFree(db, aGotoChng); } /* ** chng_addr_N: | | | | | | | | 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 | } sqlite3VdbeResolveLabel(v, endDistinctTest); sqlite3DbFree(db, aGotoChng); } /* ** chng_addr_N: ** regRowid = idx(rowid) // STAT4 only ** stat_push(P, regChng, regRowid) // 3rd parameter STAT4 only ** Next csr ** if !eof(csr) goto next_row; */ #ifdef SQLITE_ENABLE_STAT4 assert( regRowid==(regStat4+2) ); if( HasRowid(pTab) ){ sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); }else{ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); int j, k, regKey; regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; j<pPk->nKeyCol; j++){ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); assert( k>=0 && k<pIdx->nColumn ); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); } sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); } #endif assert( regChng==(regStat4+1) ); sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp, (char*)&statPushFuncdef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, 2+IsStat4); sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); /* Add the entry to the stat1 table. */ callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); assert( "BBB"[0]==SQLITE_AFF_TEXT ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); #endif sqlite3VdbeChangeP5(v, OPFLAG_APPEND); /* Add the entries to the stat4 table. */ #ifdef SQLITE_ENABLE_STAT4 { int regEq = regStat1; int regLt = regStat1+1; int regDLt = regStat1+2; int regSample = regStat1+3; int regCol = regStat1+4; int regSampleRowid = regCol + nCol; |
︙ | ︙ | |||
1271 1272 1273 1274 1275 1276 1277 | addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); VdbeCoverage(v); callStatGet(v, regStat4, STAT_GET_NEQ, regEq); callStatGet(v, regStat4, STAT_GET_NLT, regLt); callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); VdbeCoverage(v); | < < < < | | 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 | addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); VdbeCoverage(v); callStatGet(v, regStat4, STAT_GET_NEQ, regEq); callStatGet(v, regStat4, STAT_GET_NLT, regLt); callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); VdbeCoverage(v); for(i=0; i<nCol; i++){ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i); } sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample); sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp); sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid); sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */ sqlite3VdbeJumpHere(v, addrIsNull); } #endif /* SQLITE_ENABLE_STAT4 */ /* End of analysis */ sqlite3VdbeJumpHere(v, addrRewind); } /* Create a single sqlite_stat1 entry containing NULL as the index |
︙ | ︙ | |||
1460 1461 1462 1463 1464 1465 1466 | Index *pIndex /* Handle extra flags for this index, if not NULL */ ){ char *z = zIntArray; int c; int i; tRowcnt v; | | | | > > | | 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 | Index *pIndex /* Handle extra flags for this index, if not NULL */ ){ char *z = zIntArray; int c; int i; tRowcnt v; #ifdef SQLITE_ENABLE_STAT4 if( z==0 ) z = ""; #else assert( z!=0 ); #endif for(i=0; *z && i<nOut; i++){ v = 0; while( (c=z[0])>='0' && c<='9' ){ v = v*10 + c - '0'; z++; } #ifdef SQLITE_ENABLE_STAT4 if( aOut ) aOut[i] = v; if( aLog ) aLog[i] = sqlite3LogEst(v); #else assert( aOut==0 ); UNUSED_PARAMETER(aOut); assert( aLog!=0 ); aLog[i] = sqlite3LogEst(v); #endif if( *z==' ' ) z++; } #ifndef SQLITE_ENABLE_STAT4 assert( pIndex!=0 ); { #else if( pIndex ){ #endif pIndex->bUnordered = 0; pIndex->noSkipScan = 0; while( z[0] ){ if( sqlite3_strglob("unordered*", z)==0 ){ pIndex->bUnordered = 1; }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ int sz = sqlite3Atoi(z+3); if( sz<2 ) sz = 2; pIndex->szIdxRow = sqlite3LogEst(sz); }else if( sqlite3_strglob("noskipscan*", z)==0 ){ pIndex->noSkipScan = 1; } #ifdef SQLITE_ENABLE_COSTMULT else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); } |
︙ | ︙ | |||
1547 1548 1549 1550 1551 1552 1553 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); } z = argv[2]; if( pIndex ){ tRowcnt *aiRowEst = 0; int nCol = pIndex->nKeyCol+1; | | | 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); } z = argv[2]; if( pIndex ){ tRowcnt *aiRowEst = 0; int nCol = pIndex->nKeyCol+1; #ifdef SQLITE_ENABLE_STAT4 /* Index.aiRowEst may already be set here if there are duplicate ** sqlite_stat1 entries for this index. In that case just clobber ** the old data with the new instead of allocating a new array. */ if( pIndex->aiRowEst==0 ){ pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db); } |
︙ | ︙ | |||
1583 1584 1585 1586 1587 1588 1589 | } /* ** If the Index.aSample variable is not NULL, delete the aSample[] array ** and its contents. */ void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ | | | | | 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 | } /* ** If the Index.aSample variable is not NULL, delete the aSample[] array ** and its contents. */ void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ #ifdef SQLITE_ENABLE_STAT4 if( pIdx->aSample ){ int j; for(j=0; j<pIdx->nSample; j++){ IndexSample *p = &pIdx->aSample[j]; sqlite3DbFree(db, p->p); } sqlite3DbFree(db, pIdx->aSample); } if( db && db->pnBytesFreed==0 ){ pIdx->nSample = 0; pIdx->aSample = 0; } #else UNUSED_PARAMETER(db); UNUSED_PARAMETER(pIdx); #endif /* SQLITE_ENABLE_STAT4 */ } #ifdef SQLITE_ENABLE_STAT4 /* ** Populate the pIdx->aAvgEq[] array based on the samples currently ** stored in pIdx->aSample[]. */ static void initAvgEq(Index *pIdx){ if( pIdx ){ IndexSample *aSample = pIdx->aSample; |
︙ | ︙ | |||
1680 1681 1682 1683 1684 1685 1686 | Table *pTab = sqlite3FindTable(db, zName, zDb); if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab); } return pIdx; } /* | | | < < | 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 | Table *pTab = sqlite3FindTable(db, zName, zDb); if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab); } return pIdx; } /* ** Load the content from either the sqlite_stat4 ** into the relevant Index.aSample[] arrays. ** ** Arguments zSql1 and zSql2 must point to SQL statements that return ** data equivalent to the following: ** ** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx ** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4 ** ** where %Q is replaced with the database name before the SQL is executed. */ static int loadStatTbl( sqlite3 *db, /* Database handle */ const char *zSql1, /* SQL statement 1 (see above) */ const char *zSql2, /* SQL statement 2 (see above) */ const char *zDb /* Database name (e.g. "main") */ ){ int rc; /* Result codes from subroutines */ sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ char *zSql; /* Text of the SQL statement */ |
︙ | ︙ | |||
1728 1729 1730 1731 1732 1733 1734 | int i; /* Bytes of space required */ tRowcnt *pSpace; zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; nSample = sqlite3_column_int(pStmt, 1); pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); | | < < | < | | | | | < | 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 | int i; /* Bytes of space required */ tRowcnt *pSpace; zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; nSample = sqlite3_column_int(pStmt, 1); pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); assert( pIdx==0 || pIdx->nSample==0 ); if( pIdx==0 ) continue; assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 ); if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ nIdxCol = pIdx->nKeyCol; }else{ nIdxCol = pIdx->nColumn; } pIdx->nSampleCol = nIdxCol; nByte = sizeof(IndexSample) * nSample; nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ pIdx->aSample = sqlite3DbMallocZero(db, nByte); |
︙ | ︙ | |||
1780 1781 1782 1783 1784 1785 1786 | int nCol = 1; /* Number of columns in index */ zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); if( pIdx==0 ) continue; /* This next condition is true if data has already been loaded from | | < | 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 | int nCol = 1; /* Number of columns in index */ zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); if( pIdx==0 ) continue; /* This next condition is true if data has already been loaded from ** the sqlite_stat4 table. */ nCol = pIdx->nSampleCol; if( pIdx!=pPrevIdx ){ initAvgEq(pPrevIdx); pPrevIdx = pIdx; } pSample = &pIdx->aSample[pIdx->nSample]; decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0); decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); |
︙ | ︙ | |||
1815 1816 1817 1818 1819 1820 1821 | } rc = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); return rc; } /* | | | < < < < < < < < < | | | | | | | 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 | } rc = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); return rc; } /* ** Load content from the sqlite_stat4 table into ** the Index.aSample[] arrays of all indices. */ static int loadStat4(sqlite3 *db, const char *zDb){ int rc = SQLITE_OK; /* Result codes from subroutines */ assert( db->lookaside.bDisable ); if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ rc = loadStatTbl(db, "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", zDb ); } return rc; } #endif /* SQLITE_ENABLE_STAT4 */ /* ** Load the content of the sqlite_stat1 and sqlite_stat4 tables. The ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] ** arrays. The contents of sqlite_stat4 are used to populate the ** Index.aSample[] arrays. ** ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR ** is returned. In this case, even if SQLITE_ENABLE_STAT4 was defined ** during compilation and the sqlite_stat4 table is present, no data is ** read from it. ** ** If SQLITE_ENABLE_STAT4 was defined during compilation and the ** sqlite_stat4 table is not present in the database, SQLITE_ERROR is ** returned. However, in this case, data is read from the sqlite_stat1 ** table (if it is present) before returning. ** ** If an OOM error occurs, this function always sets db->mallocFailed. ** This means if the caller does not care about other errors, the return ** code may be ignored. |
︙ | ︙ | |||
1881 1882 1883 1884 1885 1886 1887 | for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); pTab->tabFlags &= ~TF_HasStat1; } for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); pIdx->hasStat1 = 0; | | | 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 | for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); pTab->tabFlags &= ~TF_HasStat1; } for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); pIdx->hasStat1 = 0; #ifdef SQLITE_ENABLE_STAT4 sqlite3DeleteIndexSamples(db, pIdx); pIdx->aSample = 0; #endif } /* Load new statistics out of the sqlite_stat1 table */ sInfo.db = db; |
︙ | ︙ | |||
1909 1910 1911 1912 1913 1914 1915 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx); } /* Load the statistics from the sqlite_stat4 table. */ | | | 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx); } /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT4 if( rc==SQLITE_OK ){ db->lookaside.bDisable++; rc = loadStat4(db, sInfo.zDatabase); db->lookaside.bDisable--; } for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); |
︙ | ︙ |
Changes to src/attach.c.
︙ | ︙ | |||
295 296 297 298 299 300 301 302 303 304 305 306 307 308 | int NotUsed, sqlite3_value **argv ){ const char *zName = (const char *)sqlite3_value_text(argv[0]); sqlite3 *db = sqlite3_context_db_handle(context); int i; Db *pDb = 0; char zErr[128]; UNUSED_PARAMETER(NotUsed); if( zName==0 ) zName = ""; for(i=0; i<db->nDb; i++){ pDb = &db->aDb[i]; | > | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | int NotUsed, sqlite3_value **argv ){ const char *zName = (const char *)sqlite3_value_text(argv[0]); sqlite3 *db = sqlite3_context_db_handle(context); int i; Db *pDb = 0; HashElem *pEntry; char zErr[128]; UNUSED_PARAMETER(NotUsed); if( zName==0 ) zName = ""; for(i=0; i<db->nDb; i++){ pDb = &db->aDb[i]; |
︙ | ︙ | |||
318 319 320 321 322 323 324 325 326 327 328 329 330 331 | sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); goto detach_error; } if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){ sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); goto detach_error; } sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; pDb->pSchema = 0; sqlite3CollapseDatabaseArray(db); return; | > > > > > > > > > > > > | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); goto detach_error; } if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){ sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); goto detach_error; } /* If any TEMP triggers reference the schema being detached, move those ** triggers to reference the TEMP schema itself. */ assert( db->aDb[1].pSchema ); pEntry = sqliteHashFirst(&db->aDb[1].pSchema->trigHash); while( pEntry ){ Trigger *pTrig = (Trigger*)sqliteHashData(pEntry); if( pTrig->pTabSchema==pDb->pSchema ){ pTrig->pTabSchema = pTrig->pSchema; } pEntry = sqliteHashNext(pEntry); } sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; pDb->pSchema = 0; sqlite3CollapseDatabaseArray(db); return; |
︙ | ︙ | |||
556 557 558 559 560 561 562 563 564 565 566 567 568 569 | return 0; } int sqlite3FixExpr( DbFixer *pFix, /* Context of the fixation */ Expr *pExpr /* The expression to be fixed to one database */ ){ while( pExpr ){ if( pExpr->op==TK_VARIABLE ){ if( pFix->pParse->db->init.busy ){ pExpr->op = TK_NULL; }else{ sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); return 1; } | > | 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 | return 0; } int sqlite3FixExpr( DbFixer *pFix, /* Context of the fixation */ Expr *pExpr /* The expression to be fixed to one database */ ){ while( pExpr ){ ExprSetProperty(pExpr, EP_Indirect); if( pExpr->op==TK_VARIABLE ){ if( pFix->pParse->db->init.busy ){ pExpr->op = TK_NULL; }else{ sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); return 1; } |
︙ | ︙ |
Changes to src/auth.c.
︙ | ︙ | |||
74 75 76 77 78 79 80 | ){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif sqlite3_mutex_enter(db->mutex); db->xAuth = (sqlite3_xauth)xAuth; db->pAuthArg = pArg; | | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | ){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif sqlite3_mutex_enter(db->mutex); db->xAuth = (sqlite3_xauth)xAuth; db->pAuthArg = pArg; if( db->xAuth ) sqlite3ExpirePreparedStatements(db, 1); sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } /* ** Write an error message into pParse->zErrMsg that explains that the ** user-supplied authorization function returned an illegal value. |
︙ | ︙ |
Changes to src/backup.c.
︙ | ︙ | |||
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 | /* Detach this backup from the source pager. */ if( p->pDestDb ){ p->pSrc->nBackup--; } if( p->isAttached ){ pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); while( *pp!=p ){ pp = &(*pp)->pNext; } *pp = p->pNext; } /* If a transaction is still open on the Btree, roll it back. */ sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); | > > | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 | /* Detach this backup from the source pager. */ if( p->pDestDb ){ p->pSrc->nBackup--; } if( p->isAttached ){ pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); assert( pp!=0 ); while( *pp!=p ){ pp = &(*pp)->pNext; assert( pp!=0 ); } *pp = p->pNext; } /* If a transaction is still open on the Btree, roll it back. */ sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); |
︙ | ︙ |
Changes to src/btree.c.
︙ | ︙ | |||
1883 1884 1885 1886 1887 1888 1889 | */ testcase( gap+2==top ); testcase( gap+1==top ); testcase( gap==top ); if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){ u8 *pSpace = pageFindSlot(pPage, nByte, &rc); if( pSpace ){ | | | > > | > | 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 | */ testcase( gap+2==top ); testcase( gap+1==top ); testcase( gap==top ); if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){ u8 *pSpace = pageFindSlot(pPage, nByte, &rc); if( pSpace ){ assert( pSpace+nByte<=data+pPage->pBt->usableSize ); if( (*pIdx = (int)(pSpace-data))<=gap ){ return SQLITE_CORRUPT_PAGE(pPage); }else{ return SQLITE_OK; } }else if( rc ){ return rc; } } /* The request could not be fulfilled using a freelist slot. Check ** to see if defragmentation is necessary. |
︙ | ︙ | |||
5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 | ){ sqlite3_file *fd = sqlite3PagerFile(pBt->pPager); u8 aSave[4]; u8 *aWrite = &pBuf[-4]; assert( aWrite>=pBufStart ); /* due to (6) */ memcpy(aSave, aWrite, 4); rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); nextPage = get4byte(aWrite); memcpy(aWrite, aSave, 4); }else #endif { DbPage *pDbPage; | > | 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 | ){ sqlite3_file *fd = sqlite3PagerFile(pBt->pPager); u8 aSave[4]; u8 *aWrite = &pBuf[-4]; assert( aWrite>=pBufStart ); /* due to (6) */ memcpy(aSave, aWrite, 4); rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT; nextPage = get4byte(aWrite); memcpy(aWrite, aSave, 4); }else #endif { DbPage *pDbPage; |
︙ | ︙ | |||
7127 7128 7129 7130 7131 7132 7133 | assert( *pRC==SQLITE_OK ); assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); assert( MX_CELL(pPage->pBt)<=10921 ); assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); | < < < < < | | 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 | assert( *pRC==SQLITE_OK ); assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); assert( MX_CELL(pPage->pBt)<=10921 ); assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); assert( pPage->nFree>=0 ); if( pPage->nOverflow || sz+2>pPage->nFree ){ if( pTemp ){ memcpy(pTemp, pCell, sz); pCell = pTemp; } if( iChild ){ |
︙ | ︙ | |||
7363 7364 7365 7366 7367 7368 7369 | u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); u8 *pData; int k; /* Current slot in pCArray->apEnd[] */ u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ assert( i<iEnd ); j = get2byte(&aData[hdr+5]); | | | 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 | u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); u8 *pData; int k; /* Current slot in pCArray->apEnd[] */ u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ assert( i<iEnd ); j = get2byte(&aData[hdr+5]); if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){} pSrcEnd = pCArray->apEnd[k]; pData = pEnd; while( 1/*exit by break*/ ){ |
︙ | ︙ | |||
7455 7456 7457 7458 7459 7460 7461 | assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ if( iEnd<=iFirst ) return 0; for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){} pEnd = pCArray->apEnd[k]; while( 1 /*Exit by break*/ ){ int sz, rc; u8 *pSlot; | > | | 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 | assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ if( iEnd<=iFirst ) return 0; for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){} pEnd = pCArray->apEnd[k]; while( 1 /*Exit by break*/ ){ int sz, rc; u8 *pSlot; assert( pCArray->szCell[i]!=0 ); sz = pCArray->szCell[i]; if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){ if( (pData - pBegin)<sz ) return 1; pData -= sz; pSlot = pData; } /* pSlot and pCArray->apCell[i] will never overlap on a well-formed ** database. But they might for a corrupt database. Hence use memmove() |
︙ | ︙ | |||
7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 | int iCell = (iOld + pPg->aiOvfl[i]) - iNew; if( iCell>=0 && iCell<nNew ){ pCellptr = &pPg->aCellIdx[iCell * 2]; if( nCell>iCell ){ memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2); } nCell++; if( pageInsertArray( pPg, pBegin, &pData, pCellptr, iCell+iNew, 1, pCArray ) ) goto editpage_fail; } } | > | 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 | int iCell = (iOld + pPg->aiOvfl[i]) - iNew; if( iCell>=0 && iCell<nNew ){ pCellptr = &pPg->aCellIdx[iCell * 2]; if( nCell>iCell ){ memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2); } nCell++; cachedCellSize(pCArray, iCell+iNew); if( pageInsertArray( pPg, pBegin, &pData, pCellptr, iCell+iNew, 1, pCArray ) ) goto editpage_fail; } } |
︙ | ︙ | |||
8140 8141 8142 8143 8144 8145 8146 | ** This must be done in advance. Once the balance starts, the cell ** offset section of the btree page will be overwritten and we will no ** long be able to find the cells if a pointer to each cell is not saved ** first. */ memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); if( pOld->nOverflow>0 ){ | | | 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 | ** This must be done in advance. Once the balance starts, the cell ** offset section of the btree page will be overwritten and we will no ** long be able to find the cells if a pointer to each cell is not saved ** first. */ memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); if( pOld->nOverflow>0 ){ if( NEVER(limit<pOld->aiOvfl[0]) ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } limit = pOld->aiOvfl[0]; for(j=0; j<limit; j++){ b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell)); piCell += 2; |
︙ | ︙ | |||
8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 | nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0, nNew>=4 ? cntNew[3] - cntNew[2] - !leafData : 0, nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0, nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 0 )); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); put4byte(pRight, apNew[nNew-1]->pgno); /* If the sibling pages are not leaves, ensure that the right-child pointer ** of the right-most new sibling page is set to the value that was ** originally in the same field of the right-most old sibling page. */ if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){ MemPage *pOld = (nNew>nOld ? apNew : apOld)[nOld-1]; | > > | 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 | nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0, nNew>=4 ? cntNew[3] - cntNew[2] - !leafData : 0, nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0, nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 0 )); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); assert( nNew>=1 && nNew<=ArraySize(apNew) ); assert( apNew[nNew-1]!=0 ); put4byte(pRight, apNew[nNew-1]->pgno); /* If the sibling pages are not leaves, ensure that the right-child pointer ** of the right-most new sibling page is set to the value that was ** originally in the same field of the right-most old sibling page. */ if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){ MemPage *pOld = (nNew>nOld ? apNew : apOld)[nOld-1]; |
︙ | ︙ | |||
8771 8772 8773 8774 8775 8776 8777 | u8 aBalanceQuickSpace[13]; u8 *pFree = 0; VVA_ONLY( int balance_quick_called = 0 ); VVA_ONLY( int balance_deeper_called = 0 ); do { | | > > | < < | 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 | u8 aBalanceQuickSpace[13]; u8 *pFree = 0; VVA_ONLY( int balance_quick_called = 0 ); VVA_ONLY( int balance_deeper_called = 0 ); do { int iPage; MemPage *pPage = pCur->pPage; if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break; if( pPage->nOverflow==0 && pPage->nFree<=nMin ){ break; }else if( (iPage = pCur->iPage)==0 ){ if( pPage->nOverflow ){ /* The root page of the b-tree is overfull. In this case call the ** balance_deeper() function to create a new child for the root-page ** and copy the current contents of the root-page to it. The ** next iteration of the do-loop will balance the child page. */ assert( balance_deeper_called==0 ); VVA_ONLY( balance_deeper_called++ ); rc = balance_deeper(pPage, &pCur->apPage[1]); if( rc==SQLITE_OK ){ pCur->iPage = 1; pCur->ix = 0; pCur->aiIdx[0] = 0; pCur->apPage[0] = pPage; pCur->pPage = pCur->apPage[1]; assert( pCur->pPage->nOverflow ); } }else{ break; } }else{ MemPage * const pParent = pCur->apPage[iPage-1]; int const iIdx = pCur->aiIdx[iPage-1]; rc = sqlite3PagerWrite(pParent->pDbPage); if( rc==SQLITE_OK && pParent->nFree<0 ){ rc = btreeComputeFreeSpace(pParent); |
︙ | ︙ | |||
8939 8940 8941 8942 8943 8944 8945 | 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 */ | | > > | 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 | 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 || pCur->info.pPayload < pPage->aData + pPage->cellOffset ){ return SQLITE_CORRUPT_BKPT; } /* Overwrite the local portion first */ rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX, 0, pCur->info.nLocal); if( rc ) return rc; if( pCur->info.nLocal==nTotal ) return SQLITE_OK; |
︙ | ︙ | |||
9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 | goto end_insert; } oldCell = findCell(pPage, idx); if( !pPage->leaf ){ memcpy(newCell, oldCell, 4); } rc = clearCell(pPage, oldCell, &info); if( info.nSize==szNew && info.nLocal==info.nPayload && (!REQUIRE_PTRMAP || szNew<pPage->minLocal) ){ /* Overwrite the old cell with the new if they are the same size. ** We could also try to do this if the old cell is smaller, then add ** the leftover space to the free list. But experiments show that ** doing that is no faster then skipping this optimization and just ** calling dropCell() and insertCell(). ** ** This optimization cannot be used on an autovacuum database if the ** new entry uses overflow pages, as the insertCell() call below is ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */ assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ | > > > > > | > > | 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 | goto end_insert; } oldCell = findCell(pPage, idx); if( !pPage->leaf ){ memcpy(newCell, oldCell, 4); } rc = clearCell(pPage, oldCell, &info); testcase( pCur->curFlags & BTCF_ValidOvfl ); invalidateOverflowCache(pCur); if( info.nSize==szNew && info.nLocal==info.nPayload && (!REQUIRE_PTRMAP || szNew<pPage->minLocal) ){ /* Overwrite the old cell with the new if they are the same size. ** We could also try to do this if the old cell is smaller, then add ** the leftover space to the free list. But experiments show that ** doing that is no faster then skipping this optimization and just ** calling dropCell() and insertCell(). ** ** This optimization cannot be used on an autovacuum database if the ** new entry uses overflow pages, as the insertCell() call below is ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */ assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ if( oldCell < pPage->aData+pPage->hdrOffset+10 ){ return SQLITE_CORRUPT_BKPT; } if( oldCell+szNew > pPage->aDataEnd ){ return SQLITE_CORRUPT_BKPT; } memcpy(oldCell, newCell, szNew); return SQLITE_OK; } dropCell(pPage, idx, info.nSize, &rc); if( rc ) goto end_insert; }else if( loc<0 && pPage->nCell>0 ){ assert( pPage->leaf ); |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
454 455 456 457 458 459 460 | #ifndef SQLITE_OMIT_ANALYZE sqlite3DeleteIndexSamples(db, p); #endif sqlite3ExprDelete(db, p->pPartIdxWhere); sqlite3ExprListDelete(db, p->aColExpr); sqlite3DbFree(db, p->zColAff); if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl); | | | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 | #ifndef SQLITE_OMIT_ANALYZE sqlite3DeleteIndexSamples(db, p); #endif sqlite3ExprDelete(db, p->pPartIdxWhere); sqlite3ExprListDelete(db, p->aColExpr); sqlite3DbFree(db, p->zColAff); if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl); #ifdef SQLITE_ENABLE_STAT4 sqlite3_free(p->aiRowEst); #endif sqlite3DbFree(db, p); } /* ** For the index called zIdxName which is found in the database iDb, |
︙ | ︙ | |||
827 828 829 830 831 832 833 834 | /* ** This routine is used to check if the UTF-8 string zName is a legal ** unqualified name for a new schema object (table, index, view or ** trigger). All names are legal except those that begin with the string ** "sqlite_" (in upper, lower or mixed case). This portion of the namespace ** is reserved for internal use. */ | > > > > | > > > > > | | > > > > > > > > > > > > > > > | > | > | > | 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 | /* ** This routine is used to check if the UTF-8 string zName is a legal ** unqualified name for a new schema object (table, index, view or ** trigger). All names are legal except those that begin with the string ** "sqlite_" (in upper, lower or mixed case). This portion of the namespace ** is reserved for internal use. ** ** When parsing the sqlite_master table, this routine also checks to ** make sure the "type", "name", and "tbl_name" columns are consistent ** with the SQL. */ int sqlite3CheckObjectName( Parse *pParse, /* Parsing context */ const char *zName, /* Name of the object to check */ const char *zType, /* Type of this object */ const char *zTblName /* Parent table name for triggers and indexes */ ){ sqlite3 *db = pParse->db; if( sqlite3WritableSchema(db) || db->init.imposterTable ){ /* Skip these error checks for writable_schema=ON */ return SQLITE_OK; } if( db->init.busy ){ if( sqlite3_stricmp(zType, db->init.azInit[0]) || sqlite3_stricmp(zName, db->init.azInit[1]) || sqlite3_stricmp(zTblName, db->init.azInit[2]) ){ if( sqlite3Config.bExtraSchemaChecks ){ sqlite3ErrorMsg(pParse, ""); /* corruptSchema() will supply the error */ return SQLITE_ERROR; } } }else{ if( pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); return SQLITE_ERROR; } } return SQLITE_OK; } /* ** Return the PRIMARY KEY index of a table */ |
︙ | ︙ | |||
914 915 916 917 918 919 920 | zName = sqlite3NameFromToken(db, pName); if( IN_RENAME_OBJECT ){ sqlite3RenameTokenMap(pParse, (void*)zName, pName); } } pParse->sNameToken = *pName; if( zName==0 ) return; | | | 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 | zName = sqlite3NameFromToken(db, pName); if( IN_RENAME_OBJECT ){ sqlite3RenameTokenMap(pParse, (void*)zName, pName); } } pParse->sNameToken = *pName; if( zName==0 ) return; if( sqlite3CheckObjectName(pParse, zName, isView?"view":"table", zName) ){ goto begin_table_error; } if( db->init.iDb==1 ) isTemp = 1; #ifndef SQLITE_OMIT_AUTHORIZATION assert( isTemp==0 || isTemp==1 ); assert( isView==0 || isView==1 ); { |
︙ | ︙ | |||
1414 1415 1416 1417 1418 1419 1420 | Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr); sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr); } pTab->iPKey = iCol; pTab->keyConf = (u8)onError; assert( autoInc==0 || autoInc==1 ); pTab->tabFlags |= autoInc*TF_Autoincrement; | | | 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 | Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr); sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr); } pTab->iPKey = iCol; pTab->keyConf = (u8)onError; assert( autoInc==0 || autoInc==1 ); pTab->tabFlags |= autoInc*TF_Autoincrement; if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags; }else if( autoInc ){ #ifndef SQLITE_OMIT_AUTOINCREMENT sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " "INTEGER PRIMARY KEY"); #endif }else{ sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, |
︙ | ︙ | |||
1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 | ** ** For virtual tables, only (1) is performed. */ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ Index *pIdx; Index *pPk; int nPk; int i, j; sqlite3 *db = pParse->db; Vdbe *v = pParse->pVdbe; /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables) */ if( !db->init.imposterTable ){ | > | 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 | ** ** For virtual tables, only (1) is performed. */ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ Index *pIdx; Index *pPk; int nPk; int nExtra; int i, j; sqlite3 *db = pParse->db; Vdbe *v = pParse->pVdbe; /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables) */ if( !db->init.imposterTable ){ |
︙ | ︙ | |||
1864 1865 1866 1867 1868 1869 1870 | sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); if( pList==0 ) return; if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); } | | > > > | | 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 | sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); if( pList==0 ) return; if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); } pList->a[0].sortFlags = pParse->iPkSortOrder; assert( pParse->pNewTable==pTab ); pTab->iPKey = -1; sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, SQLITE_IDXTYPE_PRIMARYKEY); if( db->mallocFailed || pParse->nErr ) return; pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk->nKeyCol==1 ); }else{ pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk!=0 ); /* ** Remove all redundant columns from the PRIMARY KEY. For example, change ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later ** code assumes the PRIMARY KEY contains no repeated columns. */ for(i=j=1; i<pPk->nKeyCol; i++){ if( isDupColumn(pPk, j, pPk, i) ){ pPk->nColumn--; }else{ testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ); pPk->azColl[j] = pPk->azColl[i]; pPk->aSortOrder[j] = pPk->aSortOrder[i]; pPk->aiColumn[j++] = pPk->aiColumn[i]; } } pPk->nKeyCol = j; } assert( pPk!=0 ); pPk->isCovering = 1; if( !db->init.imposterTable ) pPk->uniqNotNull = 1; nPk = pPk->nColumn = pPk->nKeyCol; /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master ** table entry. This is only required if currently generating VDBE ** code for a CREATE TABLE (not when parsing one as part of reading ** a database schema). */ if( v && pPk->tnum>0 ){ assert( db->init.busy==0 ); |
︙ | ︙ | |||
1943 1944 1945 1946 1947 1948 1949 | } assert( pIdx->nColumn>=pIdx->nKeyCol+n ); assert( pIdx->nColumn>=j ); } /* Add all table columns to the PRIMARY KEY index */ | > | > > | | | | | | | | | | | < < < | 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 | } assert( pIdx->nColumn>=pIdx->nKeyCol+n ); assert( pIdx->nColumn>=j ); } /* Add all table columns to the PRIMARY KEY index */ nExtra = 0; for(i=0; i<pTab->nCol; i++){ if( !hasColumn(pPk->aiColumn, nPk, i) ) nExtra++; } if( resizeIndexObject(db, pPk, nPk+nExtra) ) return; for(i=0, j=nPk; i<pTab->nCol; i++){ if( !hasColumn(pPk->aiColumn, j, i) ){ assert( j<pPk->nColumn ); pPk->aiColumn[j] = i; pPk->azColl[j] = sqlite3StrBINARY; j++; } } assert( pPk->nColumn==j ); assert( pTab->nCol<=j ); recomputeColumnsNotIndexed(pPk); } #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Return true if zName is a shadow table name in the current database ** connection. |
︙ | ︙ | |||
2154 2155 2156 2157 2158 2159 2160 | sqlite3MayAbort(pParse); sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); pParse->nTab = 2; addrTop = sqlite3VdbeCurrentAddr(v) + 1; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); if( pParse->nErr ) return; | | | 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 | sqlite3MayAbort(pParse); sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); pParse->nTab = 2; addrTop = sqlite3VdbeCurrentAddr(v) + 1; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); if( pParse->nErr ) return; pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect, SQLITE_AFF_BLOB); if( pSelTab==0 ) return; assert( p->aCol==0 ); p->nCol = pSelTab->nCol; p->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; sqlite3DeleteTable(db, pSelTab); |
︙ | ︙ | |||
2418 2419 2420 2421 2422 2423 2424 | n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; db->lookaside.bDisable++; #ifndef SQLITE_OMIT_AUTHORIZATION xAuth = db->xAuth; db->xAuth = 0; | | | | > | 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 | n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; db->lookaside.bDisable++; #ifndef SQLITE_OMIT_AUTHORIZATION xAuth = db->xAuth; db->xAuth = 0; pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); db->xAuth = xAuth; #else pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); #endif pParse->nTab = n; if( pTable->pCheck ){ /* CREATE VIEW name(arglist) AS ... ** The names of the columns in the table are taken from ** arglist which is stored in pTable->pCheck. The pCheck field ** normally holds CHECK constraints on an ordinary table, but for ** a VIEW it holds the list of column names. */ sqlite3ColumnsFromExprList(pParse, pTable->pCheck, &pTable->nCol, &pTable->aCol); if( db->mallocFailed==0 && pParse->nErr==0 && pTable->nCol==pSel->pEList->nExpr ){ sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel, SQLITE_AFF_NONE); } }else if( pSelTab ){ /* CREATE VIEW name AS... without an argument list. Construct ** the column names from the SELECT statement that defines the view. */ assert( pTable->aCol==0 ); pTable->nCol = pSelTab->nCol; |
︙ | ︙ | |||
3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 | p->aSortOrder = (u8*)pExtra; p->nColumn = nCol; p->nKeyCol = nCol - 1; *ppExtra = ((char*)p) + nByte; } return p; } /* ** Create a new index for an SQL table. pName1.pName2 is the name of the index ** and pTblList is the name of the table that is to be indexed. Both will ** be NULL for a primary key or an index that is created to satisfy a ** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable ** as the table to be indexed. pParse->pNewTable is a table that is | > > > > > > > > > > > > > > > > > > > > > | 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 | p->aSortOrder = (u8*)pExtra; p->nColumn = nCol; p->nKeyCol = nCol - 1; *ppExtra = ((char*)p) + nByte; } return p; } /* ** If expression list pList contains an expression that was parsed with ** an explicit "NULLS FIRST" or "NULLS LAST" clause, leave an error in ** pParse and return non-zero. Otherwise, return zero. */ int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){ if( pList ){ int i; for(i=0; i<pList->nExpr; i++){ if( pList->a[i].bNulls ){ u8 sf = pList->a[i].sortFlags; sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", (sf==0 || sf==3) ? "FIRST" : "LAST" ); return 1; } } } return 0; } /* ** Create a new index for an SQL table. pName1.pName2 is the name of the index ** and pTblList is the name of the table that is to be indexed. Both will ** be NULL for a primary key or an index that is created to satisfy a ** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable ** as the table to be indexed. pParse->pNewTable is a table that is |
︙ | ︙ | |||
3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 | goto exit_create_index; } if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ goto exit_create_index; } if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_create_index; } /* ** Find the table that is to be indexed. Return early if not found. */ if( pTblName!=0 ){ | > > > | 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 | goto exit_create_index; } if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ goto exit_create_index; } if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_create_index; } if( sqlite3HasExplicitNulls(pParse, pList) ){ goto exit_create_index; } /* ** Find the table that is to be indexed. Return early if not found. */ if( pTblName!=0 ){ |
︙ | ︙ | |||
3268 3269 3270 3271 3272 3273 3274 | ** dealing with a primary key or UNIQUE constraint. We have to invent our ** own name. */ if( pName ){ zName = sqlite3NameFromToken(db, pName); if( zName==0 ) goto exit_create_index; assert( pName->z!=0 ); | | | 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 | ** dealing with a primary key or UNIQUE constraint. We have to invent our ** own name. */ if( pName ){ zName = sqlite3NameFromToken(db, pName); if( zName==0 ) goto exit_create_index; assert( pName->z!=0 ); if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName,"index",pTab->zName) ){ goto exit_create_index; } if( !IN_RENAME_OBJECT ){ if( !db->init.busy ){ if( sqlite3FindTable(db, zName, 0)!=0 ){ sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); goto exit_create_index; |
︙ | ︙ | |||
3334 3335 3336 3337 3338 3339 3340 | Column *pCol = &pTab->aCol[pTab->nCol-1]; pCol->colFlags |= COLFLAG_UNIQUE; sqlite3TokenInit(&prevCol, pCol->zName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); if( pList==0 ) goto exit_create_index; assert( pList->nExpr==1 ); | | | 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 | Column *pCol = &pTab->aCol[pTab->nCol-1]; pCol->colFlags |= COLFLAG_UNIQUE; sqlite3TokenInit(&prevCol, pCol->zName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); if( pList==0 ) goto exit_create_index; assert( pList->nExpr==1 ); sqlite3ExprListSetSortOrder(pList, sortOrder, SQLITE_SO_UNDEFINED); }else{ sqlite3ExprListCheckLength(pParse, pList, "index"); if( pParse->nErr ) goto exit_create_index; } /* Figure out how many bytes of space are required to store explicitly ** specified collation sequence names. |
︙ | ︙ | |||
3452 3453 3454 3455 3456 3457 3458 | zColl = pTab->aCol[j].zColl; } if( !zColl ) zColl = sqlite3StrBINARY; if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ goto exit_create_index; } pIndex->azColl[i] = zColl; | | | 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 | zColl = pTab->aCol[j].zColl; } if( !zColl ) zColl = sqlite3StrBINARY; if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ goto exit_create_index; } pIndex->azColl[i] = zColl; requestedSortOrder = pListItem->sortFlags & sortOrderMask; pIndex->aSortOrder[i] = (u8)requestedSortOrder; } /* Append the table key to the end of the index. For WITHOUT ROWID ** tables (when pPk!=0) this will be the declared PRIMARY KEY. For ** normal tables (when pPk==0) this will be the rowid. */ |
︙ | ︙ | |||
3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 | ** 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{ | > | 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 | ** 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 */ assert( pName!=0 || pStart==0 ); if( pStart ){ int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; if( pName->z[n-1]==';' ) n--; /* A named index with an explicit CREATE INDEX statement */ zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", onError==OE_None ? "" : " UNIQUE", n, pName->z); }else{ |
︙ | ︙ | |||
4669 4670 4671 4672 4673 4674 4675 | } if( pKey ){ assert( sqlite3KeyInfoIsWriteable(pKey) ); for(i=0; i<nCol; i++){ const char *zColl = pIdx->azColl[i]; pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 : sqlite3LocateCollSeq(pParse, zColl); | | > | 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 | } if( pKey ){ assert( sqlite3KeyInfoIsWriteable(pKey) ); for(i=0; i<nCol; i++){ const char *zColl = pIdx->azColl[i]; pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 : sqlite3LocateCollSeq(pParse, zColl); pKey->aSortFlags[i] = pIdx->aSortOrder[i]; assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) ); } if( pParse->nErr ){ assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ ); if( pIdx->bNoQuery==0 ){ /* Deactivate the index because it contains an unknown collating ** sequence. The only way to reactive the index is to reload the ** schema. Adding the missing collating sequence later does not |
︙ | ︙ |
Changes to src/ctime.c.
︙ | ︙ | |||
302 303 304 305 306 307 308 | "ENABLE_SORTER_REFERENCES", #endif #if SQLITE_ENABLE_SQLLOG "ENABLE_SQLLOG", #endif #if defined(SQLITE_ENABLE_STAT4) "ENABLE_STAT4", | < < | 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | "ENABLE_SORTER_REFERENCES", #endif #if SQLITE_ENABLE_SQLLOG "ENABLE_SQLLOG", #endif #if defined(SQLITE_ENABLE_STAT4) "ENABLE_STAT4", #endif #if SQLITE_ENABLE_STMTVTAB "ENABLE_STMTVTAB", #endif #if SQLITE_ENABLE_STMT_SCANSTATUS "ENABLE_STMT_SCANSTATUS", #endif |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
40 41 42 43 44 45 46 | ** CREATE TABLE t1(a); ** SELECT * FROM t1 WHERE a; ** SELECT a AS b FROM t1 WHERE b; ** SELECT * FROM t1 WHERE (select a from t1); */ char sqlite3ExprAffinity(Expr *pExpr){ int op; | < | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** CREATE TABLE t1(a); ** SELECT * FROM t1 WHERE a; ** SELECT a AS b FROM t1 WHERE b; ** SELECT * FROM t1 WHERE (select a from t1); */ char sqlite3ExprAffinity(Expr *pExpr){ int op; while( ExprHasProperty(pExpr, EP_Skip) ){ assert( pExpr->op==TK_COLLATE ); pExpr = pExpr->pLeft; assert( pExpr!=0 ); } op = pExpr->op; if( op==TK_SELECT ){ |
︙ | ︙ | |||
67 68 69 70 71 72 73 | } if( op==TK_SELECT_COLUMN ){ assert( pExpr->pLeft->flags&EP_xIsSelect ); return sqlite3ExprAffinity( pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr ); } | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | } if( op==TK_SELECT_COLUMN ){ assert( pExpr->pLeft->flags&EP_xIsSelect ); return sqlite3ExprAffinity( pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr ); } return pExpr->affExpr; } /* ** Set the collating sequence for expression pExpr to be the collating ** sequence named by pToken. Return a pointer to a new Expr node that ** implements the COLLATE operator. ** |
︙ | ︙ | |||
102 103 104 105 106 107 108 | Token s; assert( zC!=0 ); sqlite3TokenInit(&s, (char*)zC); return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); } /* | > > > > > > > > > > > | > | | | 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 | Token s; assert( zC!=0 ); sqlite3TokenInit(&s, (char*)zC); return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); } /* ** Skip over any TK_COLLATE operators. */ Expr *sqlite3ExprSkipCollate(Expr *pExpr){ while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ assert( pExpr->op==TK_COLLATE ); pExpr = pExpr->pLeft; } return pExpr; } /* ** Skip over any TK_COLLATE operators and/or any unlikely() ** or likelihood() or likely() functions at the root of an ** expression. */ Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){ while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){ if( ExprHasProperty(pExpr, EP_Unlikely) ){ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); assert( pExpr->x.pList->nExpr>0 ); assert( pExpr->op==TK_FUNCTION ); pExpr = pExpr->x.pList->a[0].pExpr; }else{ |
︙ | ︙ | |||
140 141 142 143 144 145 146 | */ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ sqlite3 *db = pParse->db; CollSeq *pColl = 0; Expr *p = pExpr; while( p ){ int op = p->op; | < | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | */ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ sqlite3 *db = pParse->db; CollSeq *pColl = 0; Expr *p = pExpr; while( p ){ int op = p->op; if( op==TK_REGISTER ) op = p->op2; if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER) && p->y.pTab!=0 ){ /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally ** a TK_COLUMN but was previously evaluated and cached in a register */ int j = p->iColumn; |
︙ | ︙ | |||
226 227 228 229 230 231 232 | /* ** pExpr is an operand of a comparison operator. aff2 is the ** type affinity of the other operand. This routine returns the ** type affinity that should be used for the comparison operator. */ char sqlite3CompareAffinity(Expr *pExpr, char aff2){ char aff1 = sqlite3ExprAffinity(pExpr); | | < < < < < | | | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | /* ** pExpr is an operand of a comparison operator. aff2 is the ** type affinity of the other operand. This routine returns the ** type affinity that should be used for the comparison operator. */ char sqlite3CompareAffinity(Expr *pExpr, char aff2){ char aff1 = sqlite3ExprAffinity(pExpr); if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){ /* Both sides of the comparison are columns. If one has numeric ** affinity, use that. Otherwise use no affinity. */ if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){ return SQLITE_AFF_NUMERIC; }else{ return SQLITE_AFF_BLOB; } }else{ /* One side is a column, the other is not. Use the columns affinity. */ assert( aff1<=SQLITE_AFF_NONE || aff2<=SQLITE_AFF_NONE ); return (aff1<=SQLITE_AFF_NONE ? aff2 : aff1) | SQLITE_AFF_NONE; } } /* ** pExpr is a comparison operator. Return the type affinity that should ** be applied to both operands prior to doing the comparison. */ |
︙ | ︙ | |||
276 277 278 279 280 281 282 | ** pExpr is a comparison expression, eg. '=', '<', IN(...) etc. ** idx_affinity is the affinity of an indexed column. Return true ** if the index with affinity idx_affinity may be used to implement ** the comparison in pExpr. */ int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){ char aff = comparisonAffinity(pExpr); | < | | > | | < < > | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | ** pExpr is a comparison expression, eg. '=', '<', IN(...) etc. ** idx_affinity is the affinity of an indexed column. Return true ** if the index with affinity idx_affinity may be used to implement ** the comparison in pExpr. */ int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){ char aff = comparisonAffinity(pExpr); if( aff<SQLITE_AFF_TEXT ){ return 1; } if( aff==SQLITE_AFF_TEXT ){ return idx_affinity==SQLITE_AFF_TEXT; } return sqlite3IsNumericAffinity(idx_affinity); } /* ** Return the P5 value that should be used for a binary comparison ** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2. */ static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){ |
︙ | ︙ | |||
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 | } #endif if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ /* The Expr.x union is never used at the same time as Expr.pRight */ assert( p->x.pList==0 || p->pRight==0 ); if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); if( p->pRight ){ sqlite3ExprDeleteNN(db, p->pRight); }else if( ExprHasProperty(p, EP_xIsSelect) ){ sqlite3SelectDelete(db, p->x.pSelect); }else{ sqlite3ExprListDelete(db, p->x.pList); | > > < > | < | > > | 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 | } #endif if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ /* The Expr.x union is never used at the same time as Expr.pRight */ assert( p->x.pList==0 || p->pRight==0 ); if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); if( p->pRight ){ assert( !ExprHasProperty(p, EP_WinFunc) ); sqlite3ExprDeleteNN(db, p->pRight); }else if( ExprHasProperty(p, EP_xIsSelect) ){ assert( !ExprHasProperty(p, EP_WinFunc) ); sqlite3SelectDelete(db, p->x.pSelect); }else{ sqlite3ExprListDelete(db, p->x.pList); #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(p, EP_WinFunc) ){ sqlite3WindowDelete(db, p->y.pWin); } #endif } } if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); if( !ExprHasProperty(p, EP_Static) ){ sqlite3DbFreeNN(db, p); } } |
︙ | ︙ | |||
1079 1080 1081 1082 1083 1084 1085 | */ static int exprStructSize(Expr *p){ if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE; if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE; return EXPR_FULLSIZE; } | < < < < < < < < < < | 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 | */ static int exprStructSize(Expr *p){ if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE; if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE; return EXPR_FULLSIZE; } /* ** The dupedExpr*Size() routines each return the number of bytes required ** to store a copy of an expression or expression tree. They differ in ** how much of the tree is measured. ** ** dupedExprStructSize() Size of only the Expr structure ** dupedExprNodeSize() Size of Expr + space for token |
︙ | ︙ | |||
1328 1329 1330 1331 1332 1333 1334 | /* ** The gatherSelectWindows() procedure and its helper routine ** gatherSelectWindowsCallback() are used to scan all the expressions ** an a newly duplicated SELECT statement and gather all of the Window ** objects found there, assembling them onto the linked list at Select->pWin. */ static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){ | | < | | > > > > | 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 | /* ** The gatherSelectWindows() procedure and its helper routine ** gatherSelectWindowsCallback() are used to scan all the expressions ** an a newly duplicated SELECT statement and gather all of the Window ** objects found there, assembling them onto the linked list at Select->pWin. */ static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_WinFunc) ){ Select *pSelect = pWalker->u.pSelect; Window *pWin = pExpr->y.pWin; assert( pWin ); assert( IsWindowFunc(pExpr) ); assert( pWin->ppThis==0 ); sqlite3WindowLink(pSelect, pWin); } return WRC_Continue; } static int gatherSelectWindowsSelectCallback(Walker *pWalker, Select *p){ return p==pWalker->u.pSelect ? WRC_Continue : WRC_Prune; } static void gatherSelectWindows(Select *p){ |
︙ | ︙ | |||
1405 1406 1407 1408 1409 1410 1411 | assert( pNewExpr->iColumn==pItem[-1].pExpr->iColumn+1 ); assert( pPriorSelectCol==pItem[-1].pExpr->pLeft ); pNewExpr->pLeft = pPriorSelectCol; } } pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); | | > | 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 | assert( pNewExpr->iColumn==pItem[-1].pExpr->iColumn+1 ); assert( pPriorSelectCol==pItem[-1].pExpr->pLeft ); pNewExpr->pLeft = pPriorSelectCol; } } pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); pItem->sortFlags = pOldItem->sortFlags; pItem->done = 0; pItem->bNulls = pOldItem->bNulls; pItem->bSpanIsTab = pOldItem->bSpanIsTab; pItem->bSorterRef = pOldItem->bSorterRef; pItem->u = pOldItem->u; } return pNew; } |
︙ | ︙ | |||
1517 1518 1519 1520 1521 1522 1523 | pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; pNew->pWith = withDup(db, p->pWith); #ifndef SQLITE_OMIT_WINDOWFUNC pNew->pWin = 0; pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); | | | 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 | pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; pNew->pWith = withDup(db, p->pWith); #ifndef SQLITE_OMIT_WINDOWFUNC pNew->pWin = 0; pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew); #endif pNew->selId = p->selId; *pp = pNew; pp = &pNew->pPrior; pNext = pNew; } |
︙ | ︙ | |||
1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 | sqlite3ErrorMsg(pParse, "%d columns assigned %d values", pColumns->nId, n); goto vector_append_error; } for(i=0; i<pColumns->nId; i++){ Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i); pList = sqlite3ExprListAppend(pParse, pList, pSubExpr); if( pList ){ assert( pList->nExpr==iFirst+i+1 ); pList->a[pList->nExpr-1].zName = pColumns->a[i].zName; pColumns->a[i].zName = 0; } } | > > > > | 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 | sqlite3ErrorMsg(pParse, "%d columns assigned %d values", pColumns->nId, n); goto vector_append_error; } for(i=0; i<pColumns->nId; i++){ Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i); assert( pSubExpr!=0 || db->mallocFailed ); assert( pSubExpr==0 || pSubExpr->iTable==0 ); if( pSubExpr==0 ) continue; pSubExpr->iTable = pColumns->nId; pList = sqlite3ExprListAppend(pParse, pList, pSubExpr); if( pList ){ assert( pList->nExpr==iFirst+i+1 ); pList->a[pList->nExpr-1].zName = pColumns->a[i].zName; pColumns->a[i].zName = 0; } } |
︙ | ︙ | |||
1658 1659 1660 1661 1662 1663 1664 | sqlite3IdListDelete(db, pColumns); return pList; } /* ** Set the sort order for the last element on the given ExprList. */ | | > > > | | | | > > > > > | > > > > | > > > > > > > | 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 | sqlite3IdListDelete(db, pColumns); return pList; } /* ** Set the sort order for the last element on the given ExprList. */ void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){ struct ExprList_item *pItem; if( p==0 ) return; assert( p->nExpr>0 ); assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC==0 && SQLITE_SO_DESC>0 ); assert( iSortOrder==SQLITE_SO_UNDEFINED || iSortOrder==SQLITE_SO_ASC || iSortOrder==SQLITE_SO_DESC ); assert( eNulls==SQLITE_SO_UNDEFINED || eNulls==SQLITE_SO_ASC || eNulls==SQLITE_SO_DESC ); pItem = &p->a[p->nExpr-1]; assert( pItem->bNulls==0 ); if( iSortOrder==SQLITE_SO_UNDEFINED ){ iSortOrder = SQLITE_SO_ASC; } pItem->sortFlags = (u8)iSortOrder; if( eNulls!=SQLITE_SO_UNDEFINED ){ pItem->bNulls = 1; if( iSortOrder!=eNulls ){ pItem->sortFlags |= KEYINFO_ORDER_BIGNULL; } } } /* ** Set the ExprList.a[].zName element of the most recently added item ** on the expression list. ** ** pList might be NULL following an OOM error. But pName should never be |
︙ | ︙ | |||
2165 2166 2167 2168 2169 2170 2171 2172 | ** This routine is used to determine if the OP_Affinity operation ** can be omitted. When in doubt return FALSE. A false negative ** is harmless. A false positive, however, can result in the wrong ** answer. */ int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ u8 op; if( aff==SQLITE_AFF_BLOB ) return 1; | > | > > > | | | | < | | 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 | ** This routine is used to determine if the OP_Affinity operation ** can be omitted. When in doubt return FALSE. A false negative ** is harmless. A false positive, however, can result in the wrong ** answer. */ int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ u8 op; int unaryMinus = 0; if( aff==SQLITE_AFF_BLOB ) return 1; while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ if( p->op==TK_UMINUS ) unaryMinus = 1; p = p->pLeft; } op = p->op; if( op==TK_REGISTER ) op = p->op2; switch( op ){ case TK_INTEGER: { return aff>=SQLITE_AFF_NUMERIC; } case TK_FLOAT: { return aff>=SQLITE_AFF_NUMERIC; } case TK_STRING: { return !unaryMinus && aff==SQLITE_AFF_TEXT; } case TK_BLOB: { return !unaryMinus; } case TK_COLUMN: { assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */ return aff>=SQLITE_AFF_NUMERIC && p->iColumn<0; } default: { return 0; } } } |
︙ | ︙ | |||
2368 2369 2370 2371 2372 2373 2374 | ** CREATE INDEX i1 ON t1(b, c, a); ** ** then aiMap[] is populated with {2, 0, 1}. */ #ifndef SQLITE_OMIT_SUBQUERY int sqlite3FindInIndex( Parse *pParse, /* Parsing context */ | | | 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 | ** CREATE INDEX i1 ON t1(b, c, a); ** ** then aiMap[] is populated with {2, 0, 1}. */ #ifndef SQLITE_OMIT_SUBQUERY int sqlite3FindInIndex( Parse *pParse, /* Parsing context */ Expr *pX, /* The IN expression */ u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */ int *prRhsHasNull, /* Register holding NULL status. See notes */ int *aiMap, /* Mapping from Index fields to RHS fields */ int *piTab /* OUT: index to use */ ){ Select *p; /* SELECT to the right of IN operator */ int eType = 0; /* Type of RHS table. IN_INDEX_* */ |
︙ | ︙ | |||
2793 2794 2795 2796 2797 2798 2799 | ** that columns affinity when building index keys. If <expr> is not ** a column, use numeric affinity. */ char affinity; /* Affinity of the LHS of the IN */ int i; ExprList *pList = pExpr->x.pList; struct ExprList_item *pItem; | | | | 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 | ** that columns affinity when building index keys. If <expr> is not ** a column, use numeric affinity. */ char affinity; /* Affinity of the LHS of the IN */ int i; ExprList *pList = pExpr->x.pList; struct ExprList_item *pItem; int r1, r2; affinity = sqlite3ExprAffinity(pLeft); if( affinity<=SQLITE_AFF_NONE ){ affinity = SQLITE_AFF_BLOB; } if( pKeyInfo ){ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); } |
︙ | ︙ | |||
2821 2822 2823 2824 2825 2826 2827 | if( addrOnce && !sqlite3ExprIsConstant(pE2) ){ sqlite3VdbeChangeToNoop(v, addrOnce); ExprClearProperty(pExpr, EP_Subrtn); addrOnce = 0; } /* Evaluate the expression and insert it into the temp table */ | | | | | 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 | if( addrOnce && !sqlite3ExprIsConstant(pE2) ){ sqlite3VdbeChangeToNoop(v, addrOnce); ExprClearProperty(pExpr, EP_Subrtn); addrOnce = 0; } /* Evaluate the expression and insert it into the temp table */ sqlite3ExprCode(pParse, pE2, r1); sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1); } sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r2); } if( pKeyInfo ){ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); } |
︙ | ︙ | |||
2849 2850 2851 2852 2853 2854 2855 | ** or EXISTS operator: ** ** (SELECT a FROM b) -- subquery ** EXISTS (SELECT a FROM b) -- EXISTS subquery ** ** The pExpr parameter is the SELECT or EXISTS operator to be coded. ** | | | 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 | ** or EXISTS operator: ** ** (SELECT a FROM b) -- subquery ** EXISTS (SELECT a FROM b) -- EXISTS subquery ** ** The pExpr parameter is the SELECT or EXISTS operator to be coded. ** ** Return the register that holds the result. For a multi-column SELECT, ** the result is stored in a contiguous array of registers and the ** return value is the register of the left-most result column. ** Return 0 if an error occurs. */ #ifndef SQLITE_OMIT_SUBQUERY int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ int addrOnce = 0; /* Address of OP_Once at top of subroutine */ |
︙ | ︙ | |||
3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 | if( eType==IN_INDEX_NOOP ){ ExprList *pList = pExpr->x.pList; CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); int labelOk = sqlite3VdbeMakeLabel(pParse); int r2, regToFree; int regCkNull = 0; int ii; assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); if( destIfNull!=destIfFalse ){ regCkNull = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull); } for(ii=0; ii<pList->nExpr; ii++){ | > > > > > > > | > | 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 | if( eType==IN_INDEX_NOOP ){ ExprList *pList = pExpr->x.pList; CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); int labelOk = sqlite3VdbeMakeLabel(pParse); int r2, regToFree; int regCkNull = 0; int ii; int bLhsReal; /* True if the LHS of the IN has REAL affinity */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); if( destIfNull!=destIfFalse ){ regCkNull = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull); } bLhsReal = sqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL; for(ii=0; ii<pList->nExpr; ii++){ if( bLhsReal ){ r2 = regToFree = sqlite3GetTempReg(pParse); sqlite3ExprCode(pParse, pList->a[ii].pExpr, r2); sqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC); }else{ r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); } if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); } if( ii<pList->nExpr-1 || destIfNull!=destIfFalse ){ sqlite3VdbeAddOp4(v, OP_Eq, rLhs, labelOk, r2, (void*)pColl, P4_COLLSEQ); VdbeCoverageIf(v, ii<pList->nExpr-1); |
︙ | ︙ | |||
3384 3385 3386 3387 3388 3389 3390 | /* ** Convert a scalar expression node to a TK_REGISTER referencing ** register iReg. The caller must ensure that iReg already contains ** the correct value for the expression. */ static void exprToRegister(Expr *pExpr, int iReg){ | | | 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 | /* ** Convert a scalar expression node to a TK_REGISTER referencing ** register iReg. The caller must ensure that iReg already contains ** the correct value for the expression. */ static void exprToRegister(Expr *pExpr, int iReg){ Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); p->op2 = p->op; p->op = TK_REGISTER; p->iTable = iReg; ExprClearProperty(p, EP_Skip); } /* |
︙ | ︙ | |||
3485 3486 3487 3488 3489 3490 3491 | ** 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); | | > > > > > > > > > > > | > | 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 | ** 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 */ assert( pExpr->y.pTab!=0 ); assert( pExpr->iColumn>=XN_ROWID ); assert( pExpr->iColumn<pExpr->y.pTab->nCol ); if( pExpr->iColumn>=0 && pExpr->y.pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp2(v, OP_SCopy, pExpr->iColumn - pParse->iSelfTab, target); sqlite3VdbeAddOp1(v, OP_RealAffinity, target); return target; }else{ return pExpr->iColumn - pParse->iSelfTab; } }else{ /* Coding an expression that is part of an index where column names ** in the index refer to the table to which the index belongs */ iTab = pParse->iSelfTab - 1; } } return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, |
︙ | ︙ | |||
3788 3789 3790 3791 3792 3793 3794 | */ if( pDef->funcFlags & SQLITE_FUNC_AFFINITY ){ const char *azAff[] = { "blob", "text", "numeric", "integer", "real" }; char aff; assert( nFarg==1 ); aff = sqlite3ExprAffinity(pFarg->a[0].pExpr); sqlite3VdbeLoadString(v, target, | | | 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 | */ if( pDef->funcFlags & SQLITE_FUNC_AFFINITY ){ const char *azAff[] = { "blob", "text", "numeric", "integer", "real" }; char aff; assert( nFarg==1 ); aff = sqlite3ExprAffinity(pFarg->a[0].pExpr); sqlite3VdbeLoadString(v, target, (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]); return target; } #endif for(i=0; i<nFarg; i++){ if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){ testcase( i==31 ); |
︙ | ︙ | |||
3896 3897 3898 3899 3900 3901 3902 | } case TK_SELECT_COLUMN: { int n; if( pExpr->pLeft->iTable==0 ){ pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft); } assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT ); | | | | 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 | } case TK_SELECT_COLUMN: { int n; if( pExpr->pLeft->iTable==0 ){ pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft); } assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT ); if( pExpr->iTable!=0 && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) ){ sqlite3ErrorMsg(pParse, "%d columns assigned %d values", pExpr->iTable, n); } return pExpr->pLeft->iTable + pExpr->iColumn; } case TK_IN: { |
︙ | ︙ | |||
4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 | } case TK_VECTOR: { sqlite3ErrorMsg(pParse, "row value misused"); break; } case TK_IF_NULL_ROW: { int addrINR; addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable); inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); sqlite3VdbeJumpHere(v, addrINR); sqlite3VdbeChangeP3(v, addrINR, inReg); break; } /* ** Form A: | > > > > > > > > > > > > > | 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 | } case TK_VECTOR: { sqlite3ErrorMsg(pParse, "row value misused"); break; } /* TK_IF_NULL_ROW Expr nodes are inserted ahead of expressions ** that derive from the right-hand table of a LEFT JOIN. The ** Expr.iTable value is the table number for the right-hand table. ** The expression is only evaluated if that table is not currently ** on a LEFT JOIN NULL row. */ case TK_IF_NULL_ROW: { int addrINR; u8 okConstFactor = pParse->okConstFactor; addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable); /* Temporarily disable factoring of constant expressions, since ** even though expressions may appear to be constant, they are not ** really constant because they originate from the right-hand side ** of a LEFT JOIN. */ pParse->okConstFactor = 0; inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); pParse->okConstFactor = okConstFactor; sqlite3VdbeJumpHere(v, addrINR); sqlite3VdbeChangeP3(v, addrINR, inReg); break; } /* ** Form A: |
︙ | ︙ | |||
4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 | int nExpr; /* 2x number of WHEN terms */ int i; /* Loop counter */ ExprList *pEList; /* List of WHEN terms */ struct ExprList_item *aListelem; /* Array of WHEN terms */ Expr opCompare; /* The X==Ei expression */ Expr *pX; /* The X expression */ Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); assert(pExpr->x.pList->nExpr > 0); pEList = pExpr->x.pList; aListelem = pEList->a; nExpr = pEList->nExpr; endLabel = sqlite3VdbeMakeLabel(pParse); if( (pX = pExpr->pLeft)!=0 ){ | > > | > > > > | | | 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 | int nExpr; /* 2x number of WHEN terms */ int i; /* Loop counter */ ExprList *pEList; /* List of WHEN terms */ struct ExprList_item *aListelem; /* Array of WHEN terms */ Expr opCompare; /* The X==Ei expression */ Expr *pX; /* The X expression */ Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ Expr *pDel = 0; sqlite3 *db = pParse->db; assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); assert(pExpr->x.pList->nExpr > 0); pEList = pExpr->x.pList; aListelem = pEList->a; nExpr = pEList->nExpr; endLabel = sqlite3VdbeMakeLabel(pParse); if( (pX = pExpr->pLeft)!=0 ){ pDel = sqlite3ExprDup(db, pX, 0); if( db->mallocFailed ){ sqlite3ExprDelete(db, pDel); break; } testcase( pX->op==TK_COLUMN ); exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); testcase( regFree1==0 ); memset(&opCompare, 0, sizeof(opCompare)); opCompare.op = TK_EQ; opCompare.pLeft = pDel; pTest = &opCompare; /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001: ** The value in regFree1 might get SCopy-ed into the file result. ** So make sure that the regFree1 register is not reused for other ** purposes and possibly overwritten. */ regFree1 = 0; } |
︙ | ︙ | |||
4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 | sqlite3VdbeResolveLabel(v, nextCase); } if( (nExpr&1)!=0 ){ sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, target); } sqlite3VdbeResolveLabel(v, endLabel); break; } #ifndef SQLITE_OMIT_TRIGGER case TK_RAISE: { | > | | | | | | | | 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 | sqlite3VdbeResolveLabel(v, nextCase); } if( (nExpr&1)!=0 ){ sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, target); } sqlite3ExprDelete(db, pDel); sqlite3VdbeResolveLabel(v, endLabel); break; } #ifndef SQLITE_OMIT_TRIGGER case TK_RAISE: { assert( pExpr->affExpr==OE_Rollback || pExpr->affExpr==OE_Abort || pExpr->affExpr==OE_Fail || pExpr->affExpr==OE_Ignore ); if( !pParse->pTriggerTab ){ sqlite3ErrorMsg(pParse, "RAISE() may only be used within a trigger-program"); return 0; } if( pExpr->affExpr==OE_Abort ){ sqlite3MayAbort(pParse); } assert( !ExprHasProperty(pExpr, EP_IntValue) ); if( pExpr->affExpr==OE_Ignore ){ sqlite3VdbeAddOp4( v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); VdbeCoverage(v); }else{ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER, pExpr->affExpr, pExpr->u.zToken, 0, 0); } break; } #endif } sqlite3ReleaseTempReg(pParse, regFree1); |
︙ | ︙ | |||
4172 4173 4174 4175 4176 4177 4178 | ** ** If pExpr is a constant, then this routine might generate this ** code to fill the register in the initialization section of the ** VDBE program, in order to factor it out of the evaluation loop. */ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int r2; | | | 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 | ** ** If pExpr is a constant, then this routine might generate this ** code to fill the register in the initialization section of the ** VDBE program, in order to factor it out of the evaluation loop. */ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int r2; pExpr = sqlite3ExprSkipCollateAndLikely(pExpr); if( ConstFactorOk(pParse) && pExpr->op!=TK_REGISTER && sqlite3ExprIsConstantNotJoin(pExpr) ){ *pReg = 0; r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1); }else{ |
︙ | ︙ | |||
4363 4364 4365 4366 4367 4368 4369 | static void exprCodeBetween( Parse *pParse, /* Parsing and code generating context */ Expr *pExpr, /* The BETWEEN expression */ int dest, /* Jump destination or storage location */ void (*xJump)(Parse*,Expr*,int,int), /* Action to take */ int jumpIfNull /* Take the jump if the BETWEEN is NULL */ ){ | | < > > | > | | | | | | | | | | | | | | | | | | | | | | > > | 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 | static void exprCodeBetween( Parse *pParse, /* Parsing and code generating context */ Expr *pExpr, /* The BETWEEN expression */ int dest, /* Jump destination or storage location */ void (*xJump)(Parse*,Expr*,int,int), /* Action to take */ int jumpIfNull /* Take the jump if the BETWEEN is NULL */ ){ Expr exprAnd; /* The AND operator in x>=y AND x<=z */ Expr compLeft; /* The x>=y term */ Expr compRight; /* The x<=z term */ int regFree1 = 0; /* Temporary use register */ Expr *pDel = 0; sqlite3 *db = pParse->db; memset(&compLeft, 0, sizeof(Expr)); memset(&compRight, 0, sizeof(Expr)); memset(&exprAnd, 0, sizeof(Expr)); assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); pDel = sqlite3ExprDup(db, pExpr->pLeft, 0); if( db->mallocFailed==0 ){ exprAnd.op = TK_AND; exprAnd.pLeft = &compLeft; exprAnd.pRight = &compRight; compLeft.op = TK_GE; compLeft.pLeft = pDel; compLeft.pRight = pExpr->x.pList->a[0].pExpr; compRight.op = TK_LE; compRight.pLeft = pDel; compRight.pRight = pExpr->x.pList->a[1].pExpr; exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); if( xJump ){ xJump(pParse, &exprAnd, dest, jumpIfNull); }else{ /* Mark the expression is being from the ON or USING clause of a join ** so that the sqlite3ExprCodeTarget() routine will not attempt to move ** it into the Parse.pConstExpr list. We should use a new bit for this, ** for clarity, but we are out of bits in the Expr.flags field so we ** have to reuse the EP_FromJoin bit. Bummer. */ pDel->flags |= EP_FromJoin; sqlite3ExprCodeTarget(pParse, &exprAnd, dest); } sqlite3ReleaseTempReg(pParse, regFree1); } sqlite3ExprDelete(db, pDel); /* Ensure adequate test coverage */ testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 ); testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 ); testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 ); testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 ); testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 ); |
︙ | ︙ | |||
4835 4836 4837 4838 4839 4840 4841 | } if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){ return 1; } return 2; } if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ | | | < < < < < < < | > > | > > | 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 | } if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){ return 1; } return 2; } if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){ if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; #ifndef SQLITE_OMIT_WINDOWFUNC assert( pA->op==pB->op ); if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){ return 2; } if( ExprHasProperty(pA,EP_WinFunc) ){ if( sqlite3WindowCompare(pParse, pA->y.pWin, pB->y.pWin, 1)!=0 ){ return 2; } } #endif }else if( pA->op==TK_NULL ){ return 0; }else if( pA->op==TK_COLLATE ){ if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; }else if( ALWAYS(pB->u.zToken!=0) && strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ |
︙ | ︙ | |||
4902 4903 4904 4905 4906 4907 4908 | int i; if( pA==0 && pB==0 ) return 0; if( pA==0 || pB==0 ) return 1; if( pA->nExpr!=pB->nExpr ) return 1; for(i=0; i<pA->nExpr; i++){ Expr *pExprA = pA->a[i].pExpr; Expr *pExprB = pB->a[i].pExpr; | | | | > > > | | > > | | | | > > > > > > < | < < < < | > | 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 | int i; if( pA==0 && pB==0 ) return 0; if( pA==0 || pB==0 ) return 1; if( pA->nExpr!=pB->nExpr ) return 1; for(i=0; i<pA->nExpr; i++){ Expr *pExprA = pA->a[i].pExpr; Expr *pExprB = pB->a[i].pExpr; if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1; if( sqlite3ExprCompare(0, pExprA, pExprB, iTab) ) return 1; } return 0; } /* ** Like sqlite3ExprCompare() except COLLATE operators at the top-level ** are ignored. */ int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){ return sqlite3ExprCompare(0, sqlite3ExprSkipCollateAndLikely(pA), sqlite3ExprSkipCollateAndLikely(pB), iTab); } /* ** Return non-zero if Expr p can only be true if pNN is not NULL. ** ** Or if seenNot is true, return non-zero if Expr p can only be ** non-NULL if pNN is not NULL */ static int exprImpliesNotNull( Parse *pParse, /* Parsing context */ Expr *p, /* The expression to be checked */ Expr *pNN, /* The expression that is NOT NULL */ int iTab, /* Table being evaluated */ int seenNot /* Return true only if p can be any non-NULL value */ ){ assert( p ); assert( pNN ); if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){ return pNN->op!=TK_NULL; } switch( p->op ){ case TK_IN: { if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0; assert( ExprHasProperty(p,EP_xIsSelect) || (p->x.pList!=0 && p->x.pList->nExpr>0) ); return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); } case TK_BETWEEN: { ExprList *pList = p->x.pList; assert( pList!=0 ); assert( pList->nExpr==2 ); if( seenNot ) return 0; if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1) || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1) ){ return 1; } return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); } case TK_EQ: case TK_NE: case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_PLUS: case TK_MINUS: case TK_BITOR: case TK_LSHIFT: case TK_RSHIFT: case TK_CONCAT: seenNot = 1; /* Fall thru */ case TK_STAR: case TK_REM: case TK_BITAND: case TK_SLASH: { if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1; /* Fall thru into the next case */ } case TK_SPAN: case TK_COLLATE: case TK_UPLUS: case TK_UMINUS: { return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); } case TK_TRUTH: { if( seenNot ) return 0; if( p->op2!=TK_IS ) return 0; return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); } case TK_BITNOT: case TK_NOT: { return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); } } return 0; } |
︙ | ︙ | |||
5047 5048 5049 5050 5051 5052 5053 | */ 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: | < < > > > > > > > > > > > > > | 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 | */ 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_ISNULL: case TK_NOTNULL: case TK_IS: case TK_OR: case TK_CASE: case TK_IN: case TK_FUNCTION: testcase( pExpr->op==TK_ISNOT ); testcase( pExpr->op==TK_ISNULL ); testcase( pExpr->op==TK_NOTNULL ); 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; case TK_AND: if( sqlite3ExprImpliesNonNullRow(pExpr->pLeft, pWalker->u.iCur) && sqlite3ExprImpliesNonNullRow(pExpr->pRight, pWalker->u.iCur) ){ pWalker->eCode = 1; } return WRC_Prune; case TK_BETWEEN: sqlite3WalkExpr(pWalker, pExpr->pLeft); 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 |
︙ | ︙ | |||
5121 5122 5123 5124 5125 5126 5127 | ** 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; | | | 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 | ** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE ** clause requires that some column of the right table of the LEFT JOIN ** be non-NULL, then the LEFT JOIN can be safely converted into an ** ordinary join. */ int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ Walker w; p = sqlite3ExprSkipCollateAndLikely(p); while( p ){ if( p->op==TK_NOTNULL ){ p = p->pLeft; }else if( p->op==TK_AND ){ if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1; p = p->pRight; }else{ |
︙ | ︙ | |||
5227 5228 5229 5230 5231 5232 5233 | SrcList *pSrc = p->pSrc; int nSrc = pSrc ? pSrc->nSrc : 0; for(i=0; i<nSrc; i++){ if( pExpr->iTable==pSrc->a[i].iCursor ) break; } if( i<nSrc ){ p->nThis++; | | > > > > | | 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 | SrcList *pSrc = p->pSrc; int nSrc = pSrc ? pSrc->nSrc : 0; for(i=0; i<nSrc; i++){ if( pExpr->iTable==pSrc->a[i].iCursor ) break; } if( i<nSrc ){ p->nThis++; }else if( nSrc==0 || pExpr->iTable<pSrc->a[0].iCursor ){ /* In a well-formed parse tree (no name resolution errors), ** TK_COLUMN nodes with smaller Expr.iTable values are in an ** outer context. Those are the only ones to count as "other" */ p->nOther++; } } return WRC_Continue; } /* ** Determine if any of the arguments to the pExpr Function reference ** pSrcList. Return true if they do. Also return true if the function ** has no arguments or has only constant arguments. Return false if pExpr ** references columns but not columns of tables found in pSrcList. */ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ Walker w; struct SrcCount cnt; assert( pExpr->op==TK_AGG_FUNCTION ); memset(&w, 0, sizeof(w)); w.xExprCallback = exprSrcCount; w.xSelectCallback = sqlite3SelectWalkNoop; w.u.pSrcCount = &cnt; cnt.pSrc = pSrcList; cnt.nThis = 0; cnt.nOther = 0; sqlite3WalkExprList(&w, pExpr->x.pList); return cnt.nThis>0 || cnt.nOther==0; } |
︙ | ︙ |
Changes to src/fkey.c.
︙ | ︙ | |||
474 475 476 477 478 479 480 | sqlite3 *db = pParse->db; pExpr = sqlite3Expr(db, TK_REGISTER, 0); if( pExpr ){ if( iCol>=0 && iCol!=pTab->iPKey ){ pCol = &pTab->aCol[iCol]; pExpr->iTable = regBase + iCol + 1; | | | | 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | sqlite3 *db = pParse->db; pExpr = sqlite3Expr(db, TK_REGISTER, 0); if( pExpr ){ if( iCol>=0 && iCol!=pTab->iPKey ){ pCol = &pTab->aCol[iCol]; pExpr->iTable = regBase + iCol + 1; pExpr->affExpr = pCol->affinity; zColl = pCol->zColl; if( zColl==0 ) zColl = db->pDfltColl->zName; pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl); }else{ pExpr->iTable = regBase; pExpr->affExpr = SQLITE_AFF_INTEGER; } } return pExpr; } /* ** Return an Expr object that refers to column iCol of table pTab which |
︙ | ︙ | |||
1283 1284 1285 1286 1287 1288 1289 | Token tFrom; Expr *pRaise; tFrom.z = zFrom; tFrom.n = nFrom; pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); if( pRaise ){ | | | 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 | Token tFrom; Expr *pRaise; tFrom.z = zFrom; tFrom.n = nFrom; pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); if( pRaise ){ pRaise->affExpr = OE_Abort; } pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), sqlite3SrcListAppend(pParse, 0, &tFrom, 0), pWhere, 0, 0, 0, 0, 0 ); |
︙ | ︙ | |||
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 | sqlite3ExprListDelete(db, pList); sqlite3SelectDelete(db, pSelect); if( db->mallocFailed==1 ){ fkTriggerDelete(db, pTrigger); return 0; } assert( pStep!=0 ); switch( action ){ case OE_Restrict: pStep->op = TK_SELECT; break; case OE_Cascade: if( !pChanges ){ | > | 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 | sqlite3ExprListDelete(db, pList); sqlite3SelectDelete(db, pSelect); if( db->mallocFailed==1 ){ fkTriggerDelete(db, pTrigger); return 0; } assert( pStep!=0 ); assert( pTrigger!=0 ); switch( action ){ case OE_Restrict: pStep->op = TK_SELECT; break; case OE_Cascade: if( !pChanges ){ |
︙ | ︙ |
Changes to src/func.c.
︙ | ︙ | |||
1984 1985 1986 1987 1988 1989 1990 | FUNCTION(coalesce, 0, 0, 0, 0 ), FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), }; #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); #endif sqlite3WindowFunctions(); | < < < | 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 | FUNCTION(coalesce, 0, 0, 0, 0 ), FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), }; #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); #endif sqlite3WindowFunctions(); sqlite3RegisterDateTimeFunctions(); sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc)); #if 0 /* Enable to print out how the built-in functions are hashed */ { int i; FuncDef *p; |
︙ | ︙ |
Changes to src/global.c.
︙ | ︙ | |||
210 211 212 213 214 215 216 217 218 219 220 221 222 223 | SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ 1, /* bCoreMutex */ SQLITE_THREADSAFE==1, /* bFullMutex */ SQLITE_USE_URI, /* bOpenUri */ SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0, /* bSmallMalloc */ 0x7ffffffe, /* mxStrlen */ 0, /* neverCorrupt */ SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ SQLITE_STMTJRNL_SPILL, /* nStmtSpill */ {0,0,0,0,0,0,0,0}, /* m */ {0,0,0,0,0,0,0,0,0}, /* mutex */ {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ | > | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ 1, /* bCoreMutex */ SQLITE_THREADSAFE==1, /* bFullMutex */ SQLITE_USE_URI, /* bOpenUri */ SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0, /* bSmallMalloc */ 1, /* bExtraSchemaChecks */ 0x7ffffffe, /* mxStrlen */ 0, /* neverCorrupt */ SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ SQLITE_STMTJRNL_SPILL, /* nStmtSpill */ {0,0,0,0,0,0,0,0}, /* m */ {0,0,0,0,0,0,0,0,0}, /* mutex */ {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ |
︙ | ︙ | |||
256 257 258 259 260 261 262 263 264 265 266 267 268 269 | #ifndef SQLITE_UNTESTABLE 0, /* xTestCallback */ #endif 0, /* bLocaltimeFault */ 0, /* bInternalFunctions */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ }; /* ** Hash table for global functions - functions common to all ** database connections. After initialization, this table is ** read-only. */ | > | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | #ifndef SQLITE_UNTESTABLE 0, /* xTestCallback */ #endif 0, /* bLocaltimeFault */ 0, /* bInternalFunctions */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ 0, /* iPrngSeed */ }; /* ** Hash table for global functions - functions common to all ** database connections. After initialization, this table is ** read-only. */ |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
84 85 86 87 88 89 90 91 | pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); if( !pIdx->zColAff ){ sqlite3OomFault(db); return 0; } for(n=0; n<pIdx->nColumn; n++){ i16 x = pIdx->aiColumn[n]; if( x>=0 ){ | > | | < > | > | < | 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 | pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); if( !pIdx->zColAff ){ sqlite3OomFault(db); return 0; } for(n=0; n<pIdx->nColumn; n++){ i16 x = pIdx->aiColumn[n]; char aff; if( x>=0 ){ aff = pTab->aCol[x].affinity; }else if( x==XN_ROWID ){ aff = SQLITE_AFF_INTEGER; }else{ assert( x==XN_EXPR ); assert( pIdx->aColExpr!=0 ); aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); } if( aff<SQLITE_AFF_BLOB ) aff = SQLITE_AFF_BLOB; if( aff>SQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; pIdx->zColAff[n] = aff; } pIdx->zColAff[n] = 0; } return pIdx->zColAff; } |
︙ | ︙ | |||
135 136 137 138 139 140 141 142 143 144 145 | zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); if( !zColAff ){ sqlite3OomFault(db); return; } for(i=0; i<pTab->nCol; i++){ zColAff[i] = pTab->aCol[i].affinity; } do{ zColAff[i--] = 0; | > | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); if( !zColAff ){ sqlite3OomFault(db); return; } for(i=0; i<pTab->nCol; i++){ assert( pTab->aCol[i].affinity!=0 ); zColAff[i] = pTab->aCol[i].affinity; } do{ zColAff[i--] = 0; }while( i>=0 && zColAff[i]<=SQLITE_AFF_BLOB ); pTab->zColAff = zColAff; } assert( zColAff!=0 ); i = sqlite3Strlen30NN(zColAff); if( i ){ if( iReg ){ sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); |
︙ | ︙ | |||
827 828 829 830 831 832 833 834 835 836 837 838 839 840 | } #ifndef SQLITE_OMIT_UPSERT if( pUpsert ){ if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", pTab->zName); goto insert_cleanup; } pTabList->a[0].iCursor = iDataCur; pUpsert->pUpsertSrc = pTabList; pUpsert->regData = regData; pUpsert->iDataCur = iDataCur; pUpsert->iIdxCur = iIdxCur; if( pUpsert->pUpsertTarget ){ | > > > | 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 | } #ifndef SQLITE_OMIT_UPSERT if( pUpsert ){ if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", pTab->zName); goto insert_cleanup; } if( sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){ goto insert_cleanup; } pTabList->a[0].iCursor = iDataCur; pUpsert->pUpsertSrc = pTabList; pUpsert->regData = regData; pUpsert->iDataCur = iDataCur; pUpsert->iIdxCur = iIdxCur; if( pUpsert->pUpsertTarget ){ |
︙ | ︙ |
Changes to src/loadext.c.
︙ | ︙ | |||
457 458 459 460 461 462 463 | #ifdef SQLITE_ENABLE_NORMALIZE sqlite3_normalized_sql, #else 0, #endif /* Version 3.28.0 and later */ sqlite3_stmt_isexplain, | | > > | 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | #ifdef SQLITE_ENABLE_NORMALIZE sqlite3_normalized_sql, #else 0, #endif /* Version 3.28.0 and later */ sqlite3_stmt_isexplain, sqlite3_value_frombind, /* Version 3.30.0 and later */ sqlite3_drop_modules, }; /* ** Attempt to load an SQLite extension library contained in the file ** zFile. The entry point is zProc. zProc may be 0 in which case a ** default entry point name (sqlite3_extension_init) is used. Use ** of the default name is recommended. |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
832 833 834 835 836 837 838 839 840 841 842 843 844 845 | default: { static const struct { int op; /* The opcode */ u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */ } aFlagOp[] = { { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer }, { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension }, { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose }, { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG }, { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP }, { SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase }, { SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive }, | > | 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 | default: { static const struct { int op; /* The opcode */ u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */ } aFlagOp[] = { { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, { SQLITE_DBCONFIG_ENABLE_VIEW, SQLITE_EnableView }, { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer }, { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension }, { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose }, { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG }, { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP }, { SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase }, { SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive }, |
︙ | ︙ | |||
1231 1232 1233 1234 1235 1236 1237 | } sqlite3DbFree(db, pColl); } sqlite3HashClear(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ Module *pMod = (Module *)sqliteHashData(i); | < < < | | 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 | } sqlite3DbFree(db, pColl); } sqlite3HashClear(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ Module *pMod = (Module *)sqliteHashData(i); sqlite3VtabEponymousTableClear(db, pMod); sqlite3VtabModuleUnref(db, pMod); } sqlite3HashClear(&db->aModule); #endif sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ sqlite3ValueFree(db->pErr); sqlite3CloseExtensions(db); |
︙ | ︙ | |||
1716 1717 1718 1719 1720 1721 1722 | || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || (255<(nName = sqlite3Strlen30( zFunctionName))) ){ return SQLITE_MISUSE_BKPT; } assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); | > | | 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 | || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || (255<(nName = sqlite3Strlen30( zFunctionName))) ){ return SQLITE_MISUSE_BKPT; } assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|SQLITE_SUBTYPE); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); #ifndef SQLITE_OMIT_UTF16 /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. ** |
︙ | ︙ | |||
1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 | if( pDestructor ){ pDestructor->nRef++; } p->u.pDestructor = pDestructor; p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; 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; | > | 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 | if( pDestructor ){ pDestructor->nRef++; } p->u.pDestructor = pDestructor; p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; testcase( p->funcFlags & SQLITE_DETERMINISTIC ); testcase( p->funcFlags & SQLITE_DIRECTONLY ); p->xSFunc = xSFunc ? xSFunc : xStep; p->xFinalize = xFinal; p->xValue = xValue; p->xInverse = xInverse; p->pUserData = pUserData; p->nArg = (u16)nArg; return SQLITE_OK; |
︙ | ︙ | |||
3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 | db->autoCommit = 1; db->nextAutovac = -1; db->szMmap = sqlite3GlobalConfig.szMmap; db->nextPagesize = 0; db->nMaxSorterMmap = 0x7FFFFFFF; db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill /* The SQLITE_DQS compile-time option determines the default settings ** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML. ** ** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML ** ---------- ----------------------- ----------------------- | > | 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 | db->autoCommit = 1; db->nextAutovac = -1; db->szMmap = sqlite3GlobalConfig.szMmap; db->nextPagesize = 0; db->nMaxSorterMmap = 0x7FFFFFFF; db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_EnableView | SQLITE_CacheSpill /* The SQLITE_DQS compile-time option determines the default settings ** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML. ** ** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML ** ---------- ----------------------- ----------------------- |
︙ | ︙ | |||
3820 3821 3822 3823 3824 3825 3826 | ** this verb acts like PRNG_RESET. */ case SQLITE_TESTCTRL_PRNG_RESTORE: { sqlite3PrngRestoreState(); break; } | > | > > > > > > > > | > | > > | > > > | > > > > > > | 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 | ** this verb acts like PRNG_RESET. */ case SQLITE_TESTCTRL_PRNG_RESTORE: { sqlite3PrngRestoreState(); break; } /* sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, int x, sqlite3 *db); ** ** Control the seed for the pseudo-random number generator (PRNG) that ** is built into SQLite. Cases: ** ** x!=0 && db!=0 Seed the PRNG to the current value of the ** schema cookie in the main database for db, or ** x if the schema cookie is zero. This case ** is convenient to use with database fuzzers ** as it allows the fuzzer some control over the ** the PRNG seed. ** ** x!=0 && db==0 Seed the PRNG to the value of x. ** ** x==0 && db==0 Revert to default behavior of using the ** xRandomness method on the primary VFS. ** ** This test-control also resets the PRNG so that the new seed will ** be used for the next call to sqlite3_randomness(). */ case SQLITE_TESTCTRL_PRNG_SEED: { int x = va_arg(ap, int); int y; sqlite3 *db = va_arg(ap, sqlite3*); assert( db==0 || db->aDb[0].pSchema!=0 ); if( db && (y = db->aDb[0].pSchema->schema_cookie)!=0 ){ x = y; } sqlite3Config.iPrngSeed = x; sqlite3_randomness(0,0); break; } /* ** sqlite3_test_control(BITVEC_TEST, size, program) ** |
︙ | ︙ | |||
4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 | ** testing causes certain assert() statements in the code to be activated ** that demonstrat invariants on well-formed database files. */ case SQLITE_TESTCTRL_NEVER_CORRUPT: { sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); break; } /* Set the threshold at which OP_Once counters reset back to zero. ** By default this is 0x7ffffffe (over 2 billion), but that value is ** too big to test in a reasonable amount of time, so this control is ** provided to set a small and easily reachable reset value. */ case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: { | > > > > > > > > > > > | 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 | ** testing causes certain assert() statements in the code to be activated ** that demonstrat invariants on well-formed database files. */ case SQLITE_TESTCTRL_NEVER_CORRUPT: { sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); break; } /* sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, int); ** ** Set or clear a flag that causes SQLite to verify that type, name, ** and tbl_name fields of the sqlite_master table. This is normally ** on, but it is sometimes useful to turn it off for testing. */ case SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS: { sqlite3GlobalConfig.bExtraSchemaChecks = va_arg(ap, int); break; } /* Set the threshold at which OP_Once counters reset back to zero. ** By default this is 0x7ffffffe (over 2 billion), but that value is ** too big to test in a reasonable amount of time, so this control is ** provided to set a small and easily reachable reset value. */ case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: { |
︙ | ︙ |
Changes to src/memjournal.c.
︙ | ︙ | |||
92 93 94 95 96 97 98 | ){ MemJournal *p = (MemJournal *)pJfd; u8 *zOut = zBuf; int nRead = iAmt; int iChunkOffset; FileChunk *pChunk; | < < < < < | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | ){ MemJournal *p = (MemJournal *)pJfd; u8 *zOut = zBuf; int nRead = iAmt; int iChunkOffset; FileChunk *pChunk; if( (iAmt+iOfst)>p->endpoint.iOffset ){ return SQLITE_IOERR_SHORT_READ; } assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 ); if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ sqlite3_int64 iOff = 0; for(pChunk=p->pFirst; ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst; pChunk=pChunk->pNext ){ |
︙ | ︙ |
Changes to src/os.c.
︙ | ︙ | |||
254 255 256 257 258 259 260 | return pVfs->xDlSym(pVfs, pHdle, zSym); } void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ pVfs->xDlClose(pVfs, pHandle); } #endif /* SQLITE_OMIT_LOAD_EXTENSION */ int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ | > > > > > > | > > | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | return pVfs->xDlSym(pVfs, pHdle, zSym); } void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ pVfs->xDlClose(pVfs, pHandle); } #endif /* SQLITE_OMIT_LOAD_EXTENSION */ int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ if( sqlite3Config.iPrngSeed ){ memset(zBufOut, 0, nByte); if( ALWAYS(nByte>(signed)sizeof(unsigned)) ) nByte = sizeof(unsigned int); memcpy(zBufOut, &sqlite3Config.iPrngSeed, nByte); return SQLITE_OK; }else{ return pVfs->xRandomness(pVfs, nByte, zBufOut); } } int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ return pVfs->xSleep(pVfs, nMicro); } int sqlite3OsGetLastError(sqlite3_vfs *pVfs){ return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0; } |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
517 518 519 520 521 522 523 524 525 526 527 528 529 | { "lstat", (sqlite3_syscall_ptr)0, 0 }, #endif #define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) #if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) # ifdef __ANDROID__ { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 }, # else { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 }, # endif #else { "ioctl", (sqlite3_syscall_ptr)0, 0 }, #endif | > > < | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 | { "lstat", (sqlite3_syscall_ptr)0, 0 }, #endif #define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) #if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) # ifdef __ANDROID__ { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 }, #define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent) # else { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 }, #define osIoctl ((int(*)(int,unsigned long,...))aSyscall[28].pCurrent) # endif #else { "ioctl", (sqlite3_syscall_ptr)0, 0 }, #endif }; /* End of the overrideable system calls */ /* ** On some systems, calls to fchown() will trigger a message in a security ** log if they come from non-root processes. So avoid calling fchown() if |
︙ | ︙ | |||
5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 | || pInode->fileId.ino!=(u64)sStat.st_ino) ){ pInode = pInode->pNext; } if( pInode ){ UnixUnusedFd **pp; assert( sqlite3_mutex_notheld(pInode->pLockMutex) ); sqlite3_mutex_enter(pInode->pLockMutex); for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); pUnused = *pp; if( pUnused ){ *pp = pUnused->pNext; } sqlite3_mutex_leave(pInode->pLockMutex); } | > | 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 | || pInode->fileId.ino!=(u64)sStat.st_ino) ){ pInode = pInode->pNext; } if( pInode ){ UnixUnusedFd **pp; assert( sqlite3_mutex_notheld(pInode->pLockMutex) ); sqlite3_mutex_enter(pInode->pLockMutex); flags &= (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE); for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); pUnused = *pp; if( pUnused ){ *pp = pUnused->pNext; } sqlite3_mutex_leave(pInode->pLockMutex); } |
︙ | ︙ | |||
6118 6119 6120 6121 6122 6123 6124 | assert( fd>=0 ); if( pOutFlags ){ *pOutFlags = flags; } if( p->pPreallocatedUnused ){ p->pPreallocatedUnused->fd = fd; | | > | 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 | assert( fd>=0 ); if( pOutFlags ){ *pOutFlags = flags; } if( p->pPreallocatedUnused ){ p->pPreallocatedUnused->fd = fd; p->pPreallocatedUnused->flags = flags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE); } if( isDelete ){ #if OS_VXWORKS zPath = zName; #elif defined(SQLITE_UNLINK_AFTER_CLOSE) zPath = sqlite3_mprintf("%s", zName); |
︙ | ︙ | |||
7649 7650 7651 7652 7653 7654 7655 | } return rc; } default: { assert( 0 ); /* The call assures that only valid opcodes are sent */ } } | | | 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 | } return rc; } default: { assert( 0 ); /* The call assures that only valid opcodes are sent */ } } /*NOTREACHED*/ assert(0); return SQLITE_ERROR; } /* ** Within this division (the proxying locking implementation) the procedures ** above this point are all utilities. The lock-related methods of the ** proxy-locking sqlite3_io_method object follow. |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 | DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ; int rc = SQLITE_OK; if( !pShm ){ rc = winOpenSharedMemory(pDbFd); if( rc!=SQLITE_OK ) return rc; pShm = pDbFd->pShm; } pShmNode = pShm->pShmNode; sqlite3_mutex_enter(pShmNode->mutex); if( pShmNode->isUnlocked ){ rc = winLockSharedMemory(pShmNode); if( rc!=SQLITE_OK ) goto shmpage_out; | > | 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 | DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ; int rc = SQLITE_OK; if( !pShm ){ rc = winOpenSharedMemory(pDbFd); if( rc!=SQLITE_OK ) return rc; pShm = pDbFd->pShm; assert( pShm!=0 ); } pShmNode = pShm->pShmNode; sqlite3_mutex_enter(pShmNode->mutex); if( pShmNode->isUnlocked ){ rc = winLockSharedMemory(pShmNode); if( rc!=SQLITE_OK ) goto shmpage_out; |
︙ | ︙ | |||
4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 | if( rc!=SQLITE_OK ){ OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); return rc; } } if( pFd->mmapSize >= iOff+nAmt ){ *pp = &((u8 *)pFd->pMapRegion)[iOff]; pFd->nFetchOut++; } } #endif OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n", | > | 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 | if( rc!=SQLITE_OK ){ OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); return rc; } } if( pFd->mmapSize >= iOff+nAmt ){ assert( pFd->pMapRegion!=0 ); *pp = &((u8 *)pFd->pMapRegion)[iOff]; pFd->nFetchOut++; } } #endif OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n", |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
223 224 225 226 227 228 229 230 231 232 233 234 235 236 | %fallback ID ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW CONFLICT DATABASE DEFERRED DESC DETACH DO EACH END EXCLUSIVE EXPLAIN FAIL FOR IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT %ifdef SQLITE_OMIT_COMPOUND_SELECT EXCEPT INTERSECT UNION %endif SQLITE_OMIT_COMPOUND_SELECT %ifndef SQLITE_OMIT_WINDOWFUNC CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED EXCLUDE GROUPS OTHERS TIES %endif SQLITE_OMIT_WINDOWFUNC | > | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | %fallback ID ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW CONFLICT DATABASE DEFERRED DESC DETACH DO EACH END EXCLUSIVE EXPLAIN FAIL FOR IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT NULLS FIRST LAST %ifdef SQLITE_OMIT_COMPOUND_SELECT EXCEPT INTERSECT UNION %endif SQLITE_OMIT_COMPOUND_SELECT %ifndef SQLITE_OMIT_WINDOWFUNC CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED EXCLUDE GROUPS OTHERS TIES %endif SQLITE_OMIT_WINDOWFUNC |
︙ | ︙ | |||
469 470 471 472 473 474 475 476 477 478 479 480 481 482 | %include { /* ** For a compound SELECT statement, make sure p->pPrior->pNext==p for ** all elements in the list. And make sure list length does not exceed ** SQLITE_LIMIT_COMPOUND_SELECT. */ static void parserDoubleLinkSelect(Parse *pParse, Select *p){ if( p->pPrior ){ Select *pNext = 0, *pLoop; int mxSelect, cnt = 0; for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ pLoop->pNext = pNext; pLoop->selFlags |= SF_Compound; } | > | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 | %include { /* ** For a compound SELECT statement, make sure p->pPrior->pNext==p for ** all elements in the list. And make sure list length does not exceed ** SQLITE_LIMIT_COMPOUND_SELECT. */ static void parserDoubleLinkSelect(Parse *pParse, Select *p){ assert( p!=0 ); if( p->pPrior ){ Select *pNext = 0, *pLoop; int mxSelect, cnt = 0; for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ pLoop->pNext = pNext; pLoop->selFlags |= SF_Compound; } |
︙ | ︙ | |||
791 792 793 794 795 796 797 | // sort order. // %type sortlist {ExprList*} %destructor sortlist {sqlite3ExprListDelete(pParse->db, $$);} orderby_opt(A) ::= . {A = 0;} orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;} | | | | | > > > > > | 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 | // sort order. // %type sortlist {ExprList*} %destructor sortlist {sqlite3ExprListDelete(pParse->db, $$);} orderby_opt(A) ::= . {A = 0;} orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;} sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z) nulls(X). { A = sqlite3ExprListAppend(pParse,A,Y); sqlite3ExprListSetSortOrder(A,Z,X); } sortlist(A) ::= expr(Y) sortorder(Z) nulls(X). { A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/ sqlite3ExprListSetSortOrder(A,Z,X); } %type sortorder {int} sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;} sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;} sortorder(A) ::= . {A = SQLITE_SO_UNDEFINED;} %type nulls {int} nulls(A) ::= NULLS FIRST. {A = SQLITE_SO_ASC;} nulls(A) ::= NULLS LAST. {A = SQLITE_SO_DESC;} nulls(A) ::= . {A = SQLITE_SO_UNDEFINED;} %type groupby_opt {ExprList*} %destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);} groupby_opt(A) ::= . {A = 0;} groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;} %type having_opt {Expr*} %destructor having_opt {sqlite3ExprDelete(pParse->db, $$);} |
︙ | ︙ | |||
959 960 961 962 963 964 965 | ** that created the expression. */ static Expr *tokenExpr(Parse *pParse, int op, Token t){ Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); if( p ){ /* memset(p, 0, sizeof(Expr)); */ p->op = (u8)op; | | | 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 | ** that created the expression. */ static Expr *tokenExpr(Parse *pParse, int op, Token t){ Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); if( p ){ /* memset(p, 0, sizeof(Expr)); */ p->op = (u8)op; p->affExpr = 0; p->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; |
︙ | ︙ | |||
1055 1056 1057 1058 1059 1060 1061 | A = sqlite3ExprFunction(pParse, Y, &X, D); } expr(A) ::= id(X) LP STAR RP. { A = sqlite3ExprFunction(pParse, 0, &X, 0); } %ifndef SQLITE_OMIT_WINDOWFUNC | | | | 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 | A = sqlite3ExprFunction(pParse, Y, &X, D); } expr(A) ::= id(X) LP STAR RP. { A = sqlite3ExprFunction(pParse, 0, &X, 0); } %ifndef SQLITE_OMIT_WINDOWFUNC expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP filter_over(Z). { A = sqlite3ExprFunction(pParse, Y, &X, D); sqlite3WindowAttach(pParse, A, Z); } expr(A) ::= id(X) LP STAR RP filter_over(Z). { A = sqlite3ExprFunction(pParse, 0, &X, 0); sqlite3WindowAttach(pParse, A, Z); } %endif term(A) ::= CTIME_KW(OP). { A = sqlite3ExprFunction(pParse, 0, &OP, 0); |
︙ | ︙ | |||
1186 1187 1188 1189 1190 1191 1192 | ** expr1 NOT IN () ** ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ sqlite3ExprUnmapAndDelete(pParse, A); A = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1); | < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 | ** expr1 NOT IN () ** ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ sqlite3ExprUnmapAndDelete(pParse, A); A = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1); }else{ A = sqlite3PExpr(pParse, TK_IN, A, 0); if( A ){ A->x.pList = Y; sqlite3ExprSetHeightAndFlags(pParse, A); }else{ sqlite3ExprListDelete(pParse->db, Y); |
︙ | ︙ | |||
1518 1519 1520 1521 1522 1523 1524 | trigger_cmd(A) ::= scanpt(B) select(X) scanpt(E). {A = sqlite3TriggerSelectStep(pParse->db, X, B, E); /*A-overwrites-X*/} // The special RAISE expression that may occur in trigger programs expr(A) ::= RAISE LP IGNORE RP. { A = sqlite3PExpr(pParse, TK_RAISE, 0, 0); if( A ){ | | | | 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 | trigger_cmd(A) ::= scanpt(B) select(X) scanpt(E). {A = sqlite3TriggerSelectStep(pParse->db, X, B, E); /*A-overwrites-X*/} // The special RAISE expression that may occur in trigger programs expr(A) ::= RAISE LP IGNORE RP. { A = sqlite3PExpr(pParse, TK_RAISE, 0, 0); if( A ){ A->affExpr = OE_Ignore; } } expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP. { A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1); if( A ) { A->affExpr = (char)T; } } %endif !SQLITE_OMIT_TRIGGER %type raisetype {int} raisetype(A) ::= ROLLBACK. {A = OE_Rollback;} raisetype(A) ::= ABORT. {A = OE_Abort;} |
︙ | ︙ | |||
1668 1669 1670 1671 1672 1673 1674 | %type frame_opt {Window*} %destructor frame_opt {sqlite3WindowDelete(pParse->db, $$);} %type part_opt {ExprList*} %destructor part_opt {sqlite3ExprListDelete(pParse->db, $$);} | | | > > > > > > | 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 | %type frame_opt {Window*} %destructor frame_opt {sqlite3WindowDelete(pParse->db, $$);} %type part_opt {ExprList*} %destructor part_opt {sqlite3ExprListDelete(pParse->db, $$);} %type filter_clause {Expr*} %destructor filter_clause {sqlite3ExprDelete(pParse->db, $$);} %type over_clause {Window*} %destructor over_clause {sqlite3WindowDelete(pParse->db, $$);} %type filter_over {Window*} %destructor filter_over {sqlite3WindowDelete(pParse->db, $$);} %type range_or_rows {int} %type frame_bound {struct FrameBound} %destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);} %type frame_bound_s {struct FrameBound} %destructor frame_bound_s {sqlite3ExprDelete(pParse->db, $$.pExpr);} |
︙ | ︙ | |||
1735 1736 1737 1738 1739 1740 1741 | frame_exclude(A) ::= GROUP|TIES(X). {A = @X; /*A-overwrites-X*/} %type window_clause {Window*} %destructor window_clause {sqlite3WindowListDelete(pParse->db, $$);} window_clause(A) ::= WINDOW windowdefn_list(B). { A = B; } | > > > > | > > > > > > > > | > > > | < | < < < < | < < < > > > | 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 | frame_exclude(A) ::= GROUP|TIES(X). {A = @X; /*A-overwrites-X*/} %type window_clause {Window*} %destructor window_clause {sqlite3WindowListDelete(pParse->db, $$);} window_clause(A) ::= WINDOW windowdefn_list(B). { A = B; } filter_over(A) ::= filter_clause(F) over_clause(O). { O->pFilter = F; A = O; } filter_over(A) ::= over_clause(O). { A = O; } filter_over(A) ::= filter_clause(F). { A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( A ){ A->eFrmType = TK_FILTER; A->pFilter = F; }else{ sqlite3ExprDelete(pParse->db, F); } } over_clause(A) ::= OVER LP window(Z) RP. { A = Z; assert( A!=0 ); } over_clause(A) ::= OVER nm(Z). { A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( A ){ A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n); } } filter_clause(A) ::= FILTER LP WHERE expr(X) RP. { A = X; } %endif /* SQLITE_OMIT_WINDOWFUNC */ /* ** The code generator needs some extra TK_ token values for tokens that ** are synthesized and do not actually appear in the grammar: */ %token COLUMN /* Reference to a table column */ AGG_FUNCTION /* An aggregate function */ AGG_COLUMN /* An aggregated column */ TRUEFALSE /* True or false keyword */ ISNOT /* Combination of IS and NOT */ FUNCTION /* A function invocation */ UMINUS /* Unary minus */ UPLUS /* Unary plus */ TRUTH /* IS TRUE or IS FALSE or IS NOT TRUE or IS NOT FALSE */ REGISTER /* Reference to a VDBE register */ CONCURRENT /* BEGIN CONCURRENT */ VECTOR /* Vector */ SELECT_COLUMN /* Choose a single column from a multi-column SELECT */ |
︙ | ︙ |
Changes to src/pcache.c.
︙ | ︙ | |||
258 259 260 261 262 263 264 265 266 267 268 269 270 271 | */ int sqlite3PcacheInitialize(void){ if( sqlite3GlobalConfig.pcache2.xInit==0 ){ /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the ** built-in default page cache is used instead of the application defined ** page cache. */ sqlite3PCacheSetDefault(); } return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); } void sqlite3PcacheShutdown(void){ if( sqlite3GlobalConfig.pcache2.xShutdown ){ /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); | > | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | */ int sqlite3PcacheInitialize(void){ if( sqlite3GlobalConfig.pcache2.xInit==0 ){ /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the ** built-in default page cache is used instead of the application defined ** page cache. */ sqlite3PCacheSetDefault(); assert( sqlite3GlobalConfig.pcache2.xInit!=0 ); } return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); } void sqlite3PcacheShutdown(void){ if( sqlite3GlobalConfig.pcache2.xShutdown ){ /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); |
︙ | ︙ |
Changes to src/pcache1.c.
︙ | ︙ | |||
420 421 422 423 424 425 426 427 428 429 430 431 432 433 | */ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ PgHdr1 *p = 0; void *pPg; assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){ p = pCache->pFree; pCache->pFree = p->pNext; p->pNext = 0; }else{ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* The group mutex must be released before pcache1Alloc() is called. This ** is because it might call sqlite3_release_memory(), which assumes that | > | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | */ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ PgHdr1 *p = 0; void *pPg; assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){ assert( pCache->pFree!=0 ); p = pCache->pFree; pCache->pFree = p->pNext; p->pNext = 0; }else{ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* The group mutex must be released before pcache1Alloc() is called. This ** is because it might call sqlite3_release_memory(), which assumes that |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 | break; #endif case PragTyp_INDEX_INFO: if( zRight ){ Index *pIdx; Table *pTab; pIdx = sqlite3FindIndex(db, zRight, zDb); if( pIdx ){ int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema); int i; int mx; if( pPragma->iArg ){ /* PRAGMA index_xinfo (newer version with more rows and columns) */ mx = pIdx->nColumn; | > > > > > > > > > | 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 | break; #endif case PragTyp_INDEX_INFO: if( zRight ){ Index *pIdx; Table *pTab; pIdx = sqlite3FindIndex(db, zRight, zDb); if( pIdx==0 ){ /* If there is no index named zRight, check to see if there is a ** WITHOUT ROWID table named zRight, and if there is, show the ** structure of the PRIMARY KEY index for that table. */ pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); if( pTab && !HasRowid(pTab) ){ pIdx = sqlite3PrimaryKeyIndex(pTab); } } if( pIdx ){ int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema); int i; int mx; if( pPragma->iArg ){ /* PRAGMA index_xinfo (newer version with more rows and columns) */ mx = pIdx->nColumn; |
︙ | ︙ | |||
1232 1233 1234 1235 1236 1237 1238 | for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ CollSeq *pColl = (CollSeq *)sqliteHashData(p); sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName); } } break; | | | 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 | for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ CollSeq *pColl = (CollSeq *)sqliteHashData(p); sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName); } } break; #ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS case PragTyp_FUNCTION_LIST: { int i; HashElem *j; FuncDef *p; pParse->nMem = 2; for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){ for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){ |
︙ | ︙ |
Changes to src/pragma.h.
︙ | ︙ | |||
307 308 309 310 311 312 313 | {/* zName: */ "fullfsync", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_FullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) | | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | {/* zName: */ "fullfsync", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_FullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) #if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) {/* zName: */ "function_list", /* ePragTyp: */ PragTyp_FUNCTION_LIST, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 41, 2, /* iArg: */ 0 }, #endif #endif |
︙ | ︙ | |||
431 432 433 434 435 436 437 | /* ePragTyp: */ PragTyp_MMAP_SIZE, /* ePragFlg: */ 0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) #if !defined(SQLITE_OMIT_VIRTUALTABLE) | | | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | /* ePragTyp: */ PragTyp_MMAP_SIZE, /* ePragFlg: */ 0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) #if !defined(SQLITE_OMIT_VIRTUALTABLE) #if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) {/* zName: */ "module_list", /* ePragTyp: */ PragTyp_MODULE_LIST, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 9, 1, /* iArg: */ 0 }, #endif #endif |
︙ | ︙ | |||
475 476 477 478 479 480 481 | {/* zName: */ "parser_trace", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_ParserTrace }, #endif #endif | | | 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | {/* zName: */ "parser_trace", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_ParserTrace }, #endif #endif #if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) {/* zName: */ "pragma_list", /* ePragTyp: */ PragTyp_PRAGMA_LIST, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 9, 1, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
︙ | ︙ | |||
673 674 675 676 677 678 679 | {/* zName: */ "writable_schema", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; | | | 673 674 675 676 677 678 679 680 | {/* zName: */ "writable_schema", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; /* Number of pragmas: 65 on by default, 81 total. */ |
Changes to src/prepare.c.
︙ | ︙ | |||
60 61 62 63 64 65 66 | /* ** This is the callback routine for the code that initializes the ** database. See sqlite3Init() below for additional information. ** This routine is also called from the OP_ParseSchema opcode of the VDBE. ** ** Each callback contains the following information: ** | > | > | | | | | | | | > | | | | | | | | | > | > | | | | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | /* ** This is the callback routine for the code that initializes the ** database. See sqlite3Init() below for additional information. ** This routine is also called from the OP_ParseSchema opcode of the VDBE. ** ** Each callback contains the following information: ** ** argv[0] = type of object: "table", "index", "trigger", or "view". ** argv[1] = name of thing being created ** argv[2] = associated table if an index or trigger ** argv[3] = root page number for table or index. 0 for trigger or view. ** argv[4] = SQL text for the CREATE statement. ** */ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ InitData *pData = (InitData*)pInit; sqlite3 *db = pData->db; int iDb = pData->iDb; assert( argc==5 ); UNUSED_PARAMETER2(NotUsed, argc); assert( sqlite3_mutex_held(db->mutex) ); DbClearProperty(db, iDb, DB_Empty); pData->nInitRow++; if( db->mallocFailed ){ corruptSchema(pData, argv[1], 0); return 1; } assert( iDb>=0 && iDb<db->nDb ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[3]==0 ){ corruptSchema(pData, argv[1], 0); }else if( sqlite3_strnicmp(argv[4],"create ",7)==0 ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. */ int rc; u8 saved_iDb = db->init.iDb; sqlite3_stmt *pStmt; TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ assert( db->init.busy ); db->init.iDb = iDb; db->init.newTnum = sqlite3Atoi(argv[3]); db->init.orphanTrigger = 0; db->init.azInit = argv; TESTONLY(rcp = ) sqlite3_prepare(db, argv[4], -1, &pStmt, 0); rc = db->errCode; assert( (rc&0xFF)==(rcp&0xFF) ); db->init.iDb = saved_iDb; /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */ if( SQLITE_OK!=rc ){ if( db->init.orphanTrigger ){ assert( iDb==1 ); }else{ if( rc > pData->rc ) pData->rc = rc; if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ corruptSchema(pData, argv[1], sqlite3_errmsg(db)); } } } sqlite3_finalize(pStmt); }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){ corruptSchema(pData, argv[1], 0); }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE ** constraint for a CREATE TABLE. The index should have already ** been created when we processed the CREATE TABLE. All we have ** to do here is record the root page number for that index. */ Index *pIndex; pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName); if( pIndex==0 || sqlite3GetInt32(argv[3],&pIndex->tnum)==0 || pIndex->tnum<2 || sqlite3IndexHasDuplicateRootPage(pIndex) ){ corruptSchema(pData, argv[1], pIndex?"invalid rootpage":"orphan index"); } } return 0; } /* ** Attempt to read the database schema and initialize internal ** data structures for a single database file. The index of the ** database file is given by iDb. iDb==0 is used for the main ** database. iDb==1 should never be used. iDb>=2 is used for ** auxiliary databases. Return one of the SQLITE_ error codes to ** indicate success or failure. */ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ int rc; int i; #ifndef SQLITE_OMIT_DEPRECATED int size; #endif Db *pDb; char const *azArg[6]; int meta[5]; InitData initData; const char *zMasterName; int openedTransaction = 0; assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); assert( iDb>=0 && iDb<db->nDb ); assert( db->aDb[iDb].pSchema ); assert( sqlite3_mutex_held(db->mutex) ); assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); db->init.busy = 1; /* Construct the in-memory representation schema tables (sqlite_master or ** sqlite_temp_master) by invoking the parser directly. The appropriate ** table name will be inserted automatically by the parser so we can just ** use the abbreviation "x" here. The parser will also automatically tag ** the schema table as read-only. */ azArg[0] = "table"; azArg[1] = zMasterName = SCHEMA_TABLE(iDb); azArg[2] = azArg[1]; azArg[3] = "1"; azArg[4] = "CREATE TABLE x(type text,name text,tbl_name text," "rootpage int,sql text)"; azArg[5] = 0; initData.db = db; initData.iDb = iDb; initData.rc = SQLITE_OK; initData.pzErrMsg = pzErrMsg; initData.mInitFlags = mFlags; initData.nInitRow = 0; sqlite3InitCallback(&initData, 5, (char **)azArg, 0); if( initData.rc ){ rc = initData.rc; goto error_out; } /* Create a cursor to hold the database open */ |
︙ | ︙ | |||
310 311 312 313 314 315 316 | /* Read the schema information out of the schema tables */ assert( db->init.busy ); { char *zSql; zSql = sqlite3MPrintf(db, | | | 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | /* Read the schema information out of the schema tables */ assert( db->init.busy ); { char *zSql; zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\".%s ORDER BY rowid", db->aDb[iDb].zDbSName, zMasterName); #ifndef SQLITE_OMIT_AUTHORIZATION { sqlite3_xauth xAuth; xAuth = db->xAuth; db->xAuth = 0; #endif |
︙ | ︙ | |||
631 632 633 634 635 636 637 | } if( pzTail ){ *pzTail = sParse.zTail; } rc = sParse.rc; #ifndef SQLITE_OMIT_EXPLAIN | > > | > | 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 | } if( pzTail ){ *pzTail = sParse.zTail; } rc = sParse.rc; #ifndef SQLITE_OMIT_EXPLAIN /* Justification for the ALWAYS(): The only way for rc to be SQLITE_OK and ** sParse.pVdbe to be NULL is if the input SQL is an empty string, but in ** that case, sParse.explain will be false. */ if( sParse.explain && rc==SQLITE_OK && ALWAYS(sParse.pVdbe) ){ static const char * const azColName[] = { "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", "id", "parent", "notused", "detail" }; int iFirst, mx; if( sParse.explain==2 ){ sqlite3VdbeSetNumCols(sParse.pVdbe, 4); |
︙ | ︙ | |||
656 657 658 659 660 661 662 | } } #endif if( db->init.busy==0 ){ sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags); } | | | | 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | } } #endif if( db->init.busy==0 ){ sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags); } if( rc!=SQLITE_OK || db->mallocFailed ){ if( sParse.pVdbe ) sqlite3VdbeFinalize(sParse.pVdbe); assert(!(*ppStmt)); }else{ *ppStmt = (sqlite3_stmt*)sParse.pVdbe; } if( zErrMsg ){ sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); |
︙ | ︙ |
Changes to src/resolve.c.
︙ | ︙ | |||
377 378 379 380 381 382 383 | ExprSetProperty(pExpr, EP_Alias); } }else #endif /* SQLITE_OMIT_UPSERT */ { #ifndef SQLITE_OMIT_TRIGGER if( iCol<0 ){ | | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | ExprSetProperty(pExpr, EP_Alias); } }else #endif /* SQLITE_OMIT_UPSERT */ { #ifndef SQLITE_OMIT_TRIGGER if( iCol<0 ){ pExpr->affExpr = SQLITE_AFF_INTEGER; }else if( pExpr->iTable==0 ){ testcase( iCol==31 ); testcase( iCol==32 ); pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); }else{ testcase( iCol==31 ); testcase( iCol==32 ); |
︙ | ︙ | |||
409 410 411 412 413 414 415 | && pMatch && (pNC->ncFlags & NC_IdxExpr)==0 && sqlite3IsRowid(zCol) && VisibleRowid(pMatch->pTab) ){ cnt = 1; pExpr->iColumn = -1; | | | 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | && pMatch && (pNC->ncFlags & NC_IdxExpr)==0 && sqlite3IsRowid(zCol) && VisibleRowid(pMatch->pTab) ){ cnt = 1; pExpr->iColumn = -1; pExpr->affExpr = SQLITE_AFF_INTEGER; } /* ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z ** might refer to an result-set alias. This happens, for example, when ** we are resolving names in the WHERE clause of the following command: ** |
︙ | ︙ | |||
685 686 687 688 689 690 691 | assert( pSrcList && pSrcList->nSrc==1 ); pItem = pSrcList->a; assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 ); pExpr->op = TK_COLUMN; pExpr->y.pTab = pItem->pTab; pExpr->iTable = pItem->iCursor; pExpr->iColumn = -1; | | | 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 | assert( pSrcList && pSrcList->nSrc==1 ); pItem = pSrcList->a; assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 ); pExpr->op = TK_COLUMN; pExpr->y.pTab = pItem->pTab; pExpr->iTable = pItem->iCursor; pExpr->iColumn = -1; pExpr->affExpr = SQLITE_AFF_INTEGER; break; } #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */ /* A column name: ID ** Or table name and column name: ID.ID |
︙ | ︙ | |||
745 746 747 748 749 750 751 | int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ FuncDef *pDef; /* Information about the function */ u8 enc = ENC(pParse->db); /* The database encoding */ int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin)); | | > > | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 | int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ FuncDef *pDef; /* Information about the function */ u8 enc = ENC(pParse->db); /* The database encoding */ int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin)); #ifndef SQLITE_OMIT_WINDOWFUNC Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0); #endif assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); zId = pExpr->u.zToken; nId = sqlite3Strlen30(zId); pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0); if( pDef==0 ){ |
︙ | ︙ | |||
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 | && pParse->nested==0 && sqlite3Config.bInternalFunctions==0 ){ /* Internal-use-only functions are disallowed unless the ** SQL is being compiled using sqlite3NestedParse() */ no_such_func = 1; pDef = 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) ); | > > > > > > > > > | | | | | 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 | && pParse->nested==0 && sqlite3Config.bInternalFunctions==0 ){ /* Internal-use-only functions are disallowed unless the ** SQL is being compiled using sqlite3NestedParse() */ no_such_func = 1; pDef = 0; }else if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 && ExprHasProperty(pExpr, EP_Indirect) && !IN_RENAME_OBJECT ){ /* Functions tagged with SQLITE_DIRECTONLY may not be used ** inside of triggers and views */ sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views", pDef->zName); } } if( 0==IN_RENAME_OBJECT ){ #ifndef SQLITE_OMIT_WINDOWFUNC assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX) || (pDef->xValue==0 && pDef->xInverse==0) || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize) ); if( pDef && pDef->xValue==0 && pWin ){ sqlite3ErrorMsg(pParse, "%.*s() may not be used as a window function", nId, zId ); pNC->nErr++; }else if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin) || (is_agg && pWin && (pNC->ncFlags & NC_AllowWin)==0) ){ const char *zType; if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){ zType = "window"; }else{ zType = "aggregate"; } sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId); pNC->nErr++; is_agg = 0; |
︙ | ︙ | |||
865 866 867 868 869 870 871 872 873 874 875 876 | 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 ){ /* Window functions may not be arguments of aggregate functions. ** Or arguments of other window functions. But aggregate functions ** may be arguments for window functions. */ #ifndef SQLITE_OMIT_WINDOWFUNC | > > > > > > > > > | > > > > > | > | | | | < | < < < < > > > > > | | | 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 | sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); pNC->nErr++; }else if( wrong_num_args ){ sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", nId, zId); pNC->nErr++; } #ifndef SQLITE_OMIT_WINDOWFUNC else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3ErrorMsg(pParse, "FILTER may not be used with non-aggregate %.*s()", nId, zId ); pNC->nErr++; } #endif if( is_agg ){ /* Window functions may not be arguments of aggregate functions. ** Or arguments of other window functions. But aggregate functions ** may be arguments for window functions. */ #ifndef SQLITE_OMIT_WINDOWFUNC pNC->ncFlags &= ~(NC_AllowWin | (!pWin ? NC_AllowAgg : 0)); #else pNC->ncFlags &= ~NC_AllowAgg; #endif } } #ifndef SQLITE_OMIT_WINDOWFUNC else if( ExprHasProperty(pExpr, EP_WinFunc) ){ is_agg = 1; } #endif sqlite3WalkExprList(pWalker, pList); if( is_agg ){ #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ Select *pSel = pNC->pWinSelect; assert( pWin==pExpr->y.pWin ); if( IN_RENAME_OBJECT==0 ){ sqlite3WindowUpdate(pParse, pSel->pWinDefn, pWin, pDef); } sqlite3WalkExprList(pWalker, pWin->pPartition); sqlite3WalkExprList(pWalker, pWin->pOrderBy); sqlite3WalkExpr(pWalker, pWin->pFilter); sqlite3WindowLink(pSel, pWin); pNC->ncFlags |= NC_HasWin; }else #endif /* SQLITE_OMIT_WINDOWFUNC */ { NameContext *pNC2 = pNC; pExpr->op = TK_AGG_FUNCTION; pExpr->op2 = 0; #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter); } #endif while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ pExpr->op2++; pNC2 = pNC2->pNext; } assert( pDef!=0 || IN_RENAME_OBJECT ); if( pNC2 && pDef ){ assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); } } pNC->ncFlags |= savedAllowFlags; |
︙ | ︙ | |||
943 944 945 946 947 948 949 | } case TK_VARIABLE: { notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr); break; } case TK_IS: case TK_ISNOT: { | | | 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 | } case TK_VARIABLE: { notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr); break; } case TK_IS: case TK_ISNOT: { Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight); assert( !ExprHasProperty(pExpr, EP_Reduced) ); /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", ** and "x IS NOT FALSE". */ if( pRight->op==TK_ID ){ int rc = resolveExprStep(pWalker, pRight); if( rc==WRC_Abort ) return WRC_Abort; if( pRight->op==TK_TRUEFALSE ){ |
︙ | ︙ | |||
1154 1155 1156 1157 1158 1159 1160 | moreToDo = 0; pEList = pSelect->pEList; assert( pEList!=0 ); for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ int iCol = -1; Expr *pE, *pDup; if( pItem->done ) continue; | | | 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 | moreToDo = 0; pEList = pSelect->pEList; assert( pEList!=0 ); for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ int iCol = -1; Expr *pE, *pDup; if( pItem->done ) continue; pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); return 1; } }else{ iCol = resolveAsName(pParse, pEList, pE); |
︙ | ︙ | |||
1248 1249 1250 1251 1252 1253 1254 | const char *zType /* "ORDER" or "GROUP" */ ){ int i; sqlite3 *db = pParse->db; ExprList *pEList; struct ExprList_item *pItem; | | | 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 | const char *zType /* "ORDER" or "GROUP" */ ){ int i; sqlite3 *db = pParse->db; ExprList *pEList; struct ExprList_item *pItem; if( pOrderBy==0 || pParse->db->mallocFailed || IN_RENAME_OBJECT ) return 0; if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); return 1; } pEList = pSelect->pEList; assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ |
︙ | ︙ | |||
1270 1271 1272 1273 1274 1275 1276 | } } return 0; } #ifndef SQLITE_OMIT_WINDOWFUNC /* | | > | < | < < < < | > | | | | | | > | | | 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 | } } return 0; } #ifndef SQLITE_OMIT_WINDOWFUNC /* ** Walker callback for windowRemoveExprFromSelect(). */ static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){ UNUSED_PARAMETER(pWalker); if( ExprHasProperty(pExpr, EP_WinFunc) ){ Window *pWin = pExpr->y.pWin; sqlite3WindowUnlinkFromSelect(pWin); } return WRC_Continue; } /* ** Remove any Window objects owned by the expression pExpr from the ** Select.pWin list of Select object pSelect. */ static void windowRemoveExprFromSelect(Select *pSelect, Expr *pExpr){ if( pSelect->pWin ){ Walker sWalker; memset(&sWalker, 0, sizeof(Walker)); sWalker.xExprCallback = resolveRemoveWindowsCb; sWalker.u.pSelect = pSelect; sqlite3WalkExpr(&sWalker, pExpr); } } #else # define windowRemoveExprFromSelect(a, b) #endif /* SQLITE_OMIT_WINDOWFUNC */ /* ** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect. ** The Name context of the SELECT statement is pNC. zType is either ** "ORDER" or "GROUP" depending on which type of clause pOrderBy is. ** ** This routine resolves each term of the clause into an expression. |
︙ | ︙ | |||
1335 1336 1337 1338 1339 1340 1341 | int nResult; /* Number of terms in the result set */ if( pOrderBy==0 ) return 0; nResult = pSelect->pEList->nExpr; pParse = pNC->pParse; for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ Expr *pE = pItem->pExpr; | | | 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 | int nResult; /* Number of terms in the result set */ if( pOrderBy==0 ) return 0; nResult = pSelect->pEList->nExpr; pParse = pNC->pParse; for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ Expr *pE = pItem->pExpr; Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pE); if( zType[0]!='G' ){ iCol = resolveAsName(pParse, pSelect->pEList, pE2); if( iCol>0 ){ /* If an AS-name match is found, mark this ORDER BY column as being ** a copy of the iCol-th result-set column. The subsequent call to ** sqlite3ResolveOrderGroupBy() will convert the expression to a ** copy of the iCol-th result-set expression. */ |
︙ | ︙ | |||
1369 1370 1371 1372 1373 1374 1375 | return 1; } for(j=0; j<pSelect->pEList->nExpr; j++){ if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ /* Since this expresion is being changed into a reference ** to an identical expression in the result set, remove all Window ** objects belonging to the expression from the Select.pWin list. */ | | | 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 | return 1; } for(j=0; j<pSelect->pEList->nExpr; j++){ if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ /* Since this expresion is being changed into a reference ** to an identical expression in the result set, remove all Window ** objects belonging to the expression from the Select.pWin list. */ windowRemoveExprFromSelect(pSelect, pE); pItem->u.x.iOrderByCol = j+1; } } } return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); } |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
98 99 100 101 102 103 104 105 106 107 108 109 110 111 | sqlite3ExprDelete(db, p->pLimit); #ifndef SQLITE_OMIT_WINDOWFUNC if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){ sqlite3WindowListDelete(db, p->pWinDefn); } #endif if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; } } /* | > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | sqlite3ExprDelete(db, p->pLimit); #ifndef SQLITE_OMIT_WINDOWFUNC if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){ sqlite3WindowListDelete(db, p->pWinDefn); } #endif if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); assert( p->pWin==0 ); if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; } } /* |
︙ | ︙ | |||
659 660 661 662 663 664 665 | } VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat); pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); if( pParse->db->mallocFailed ) return; pOp->p2 = nKey + nData; pKI = pOp->p4.pKeyInfo; | | | 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 | } VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat); pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); if( pParse->db->mallocFailed ) return; pOp->p2 = nKey + nData; pKI = pOp->p4.pKeyInfo; memset(pKI->aSortFlags, 0, pKI->nKeyField); /* Makes OP_Jump testable */ sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); testcase( pKI->nAllField > pKI->nKeyField+2 ); pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, pKI->nAllField-pKI->nKeyField-1); addrJmp = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse); |
︙ | ︙ | |||
1270 1271 1272 1273 1274 1275 1276 | ** Allocate a KeyInfo object sufficient for an index of N key columns and ** X extra columns. */ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*); KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); if( p ){ | | | 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 | ** Allocate a KeyInfo object sufficient for an index of N key columns and ** X extra columns. */ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*); KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); if( p ){ p->aSortFlags = (u8*)&p->aColl[N+X]; p->nKeyField = (u16)N; p->nAllField = (u16)(N+X); p->enc = ENC(db); p->db = db; p->nRef = 1; memset(&p[1], 0, nExtra); }else{ |
︙ | ︙ | |||
1347 1348 1349 1350 1351 1352 1353 | nExpr = pList->nExpr; pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1); if( pInfo ){ assert( sqlite3KeyInfoIsWriteable(pInfo) ); for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){ pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr); | | | 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 | nExpr = pList->nExpr; pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1); if( pInfo ){ assert( sqlite3KeyInfoIsWriteable(pInfo) ); for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){ pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr); pInfo->aSortFlags[i-iStart] = pItem->sortFlags; } } return pInfo; } /* ** Name of the connection operator, used for error messages. |
︙ | ︙ | |||
1639 1640 1641 1642 1643 1644 1645 | char const *zOrigDb = 0; char const *zOrigTab = 0; char const *zOrigCol = 0; #endif assert( pExpr!=0 ); assert( pNC->pSrcList!=0 ); | < < | 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 | char const *zOrigDb = 0; char const *zOrigTab = 0; char const *zOrigCol = 0; #endif assert( pExpr!=0 ); assert( pNC->pSrcList!=0 ); switch( pExpr->op ){ case TK_COLUMN: { /* The expression is a column. Locate the table the column is being ** extracted from in NameContext.pSrcList. This table may be real ** database table or a subquery. */ Table *pTab = 0; /* Table structure column is extracted from */ |
︙ | ︙ | |||
1957 1958 1959 1960 1961 1962 1963 | for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){ /* Get an appropriate name for the column */ if( (zName = pEList->a[i].zName)!=0 ){ /* If the column contains an "AS <name>" phrase, use <name> as the name */ }else{ | | < | 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 | for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){ /* Get an appropriate name for the column */ if( (zName = pEList->a[i].zName)!=0 ){ /* If the column contains an "AS <name>" phrase, use <name> as the name */ }else{ Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr); while( pColExpr->op==TK_DOT ){ pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); } if( pColExpr->op==TK_COLUMN ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; Table *pTab = pColExpr->y.pTab; assert( pTab!=0 ); if( iCol<0 ) iCol = pTab->iPKey; zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid"; |
︙ | ︙ | |||
2030 2031 2032 2033 2034 2035 2036 | ** ** This routine requires that all identifiers in the SELECT ** statement be resolved. */ void sqlite3SelectAddColumnTypeAndCollation( Parse *pParse, /* Parsing contexts */ Table *pTab, /* Add column type information to this table */ | | > | 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 | ** ** This routine requires that all identifiers in the SELECT ** statement be resolved. */ void sqlite3SelectAddColumnTypeAndCollation( Parse *pParse, /* Parsing contexts */ Table *pTab, /* Add column type information to this table */ Select *pSelect, /* SELECT used to determine types and collations */ char aff /* Default affinity for columns */ ){ sqlite3 *db = pParse->db; NameContext sNC; Column *pCol; CollSeq *pColl; int i; Expr *p; |
︙ | ︙ | |||
2063 2064 2065 2066 2067 2068 2069 | n = sqlite3Strlen30(pCol->zName); pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2); if( pCol->zName ){ memcpy(&pCol->zName[n+1], zType, m+1); pCol->colFlags |= COLFLAG_HASTYPE; } } | | | | | 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 | n = sqlite3Strlen30(pCol->zName); pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2); if( pCol->zName ){ memcpy(&pCol->zName[n+1], zType, m+1); pCol->colFlags |= COLFLAG_HASTYPE; } } if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff; pColl = sqlite3ExprCollSeq(pParse, p); if( pColl && pCol->zColl==0 ){ pCol->zColl = sqlite3DbStrDup(db, pColl->zName); } } pTab->szTabRow = 1; /* Any non-zero value works */ } /* ** Given a SELECT statement, generate a Table structure that describes ** the result set of that SELECT. */ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){ Table *pTab; sqlite3 *db = pParse->db; u64 savedFlags; savedFlags = db->flags; db->flags &= ~(u64)SQLITE_FullColNames; db->flags |= SQLITE_ShortColNames; sqlite3SelectPrep(pParse, pSelect, 0); db->flags = savedFlags; if( pParse->nErr ) return 0; while( pSelect->pPrior ) pSelect = pSelect->pPrior; pTab = sqlite3DbMallocZero(db, sizeof(Table) ); if( pTab==0 ){ return 0; } pTab->nTabRef = 1; pTab->zName = 0; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect, aff); pTab->iPKey = -1; if( db->mallocFailed ){ sqlite3DeleteTable(db, pTab); return 0; } return pTab; } |
︙ | ︙ | |||
2250 2251 2252 2253 2254 2255 2256 | pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1); if( pColl==0 ) pColl = db->pDfltColl; pOrderBy->a[i].pExpr = sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName); } assert( sqlite3KeyInfoIsWriteable(pRet) ); pRet->aColl[i] = pColl; | | | 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 | pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1); if( pColl==0 ) pColl = db->pDfltColl; pOrderBy->a[i].pExpr = sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName); } assert( sqlite3KeyInfoIsWriteable(pRet) ); pRet->aColl[i] = pColl; pRet->aSortFlags[i] = pOrderBy->a[i].sortFlags; } } return pRet; } #ifndef SQLITE_OMIT_CTE |
︙ | ︙ | |||
2961 2962 2963 2964 2965 2966 2967 | pIn->iSdst, pIn->nSdst); sqlite3ReleaseTempReg(pParse, r1); break; } /* If this is a scalar select that is part of an expression, then ** store the results in the appropriate memory cell and break out | | > > | | > | 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 | pIn->iSdst, pIn->nSdst); sqlite3ReleaseTempReg(pParse, r1); break; } /* If this is a scalar select that is part of an expression, then ** store the results in the appropriate memory cell and break out ** of the scan loop. Note that the select might return multiple columns ** if it is the RHS of a row-value IN operator. */ case SRT_Mem: { if( pParse->nErr==0 ){ testcase( pIn->nSdst>1 ); sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst); } /* The LIMIT clause will jump out of the loop for us */ break; } #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ /* The results are stored in a sequence of registers ** starting at pDest->iSdst. Then the co-routine yields. |
︙ | ︙ | |||
3222 3223 3224 3225 3226 3227 3228 | pParse->nMem += nExpr+1; sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev); pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1); if( pKeyDup ){ assert( sqlite3KeyInfoIsWriteable(pKeyDup) ); for(i=0; i<nExpr; i++){ pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i); | | | 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 | pParse->nMem += nExpr+1; sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev); pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1); if( pKeyDup ){ assert( sqlite3KeyInfoIsWriteable(pKeyDup) ); for(i=0; i<nExpr; i++){ pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i); pKeyDup->aSortFlags[i] = 0; } } } /* Separate the left and the right query from one another */ p->pPrior = 0; |
︙ | ︙ | |||
3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 | } if( pNew && ExprHasProperty(pExpr,EP_FromJoin) ){ pNew->iRightJoinTable = pExpr->iRightJoinTable; ExprSetProperty(pNew, EP_FromJoin); } sqlite3ExprDelete(db, pExpr); pExpr = pNew; } } }else{ if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){ pExpr->iTable = pSubst->iNewTable; } pExpr->pLeft = substExpr(pSubst, pExpr->pLeft); | > > > > > > > > > > > > | 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 | } if( pNew && ExprHasProperty(pExpr,EP_FromJoin) ){ pNew->iRightJoinTable = pExpr->iRightJoinTable; ExprSetProperty(pNew, EP_FromJoin); } sqlite3ExprDelete(db, pExpr); pExpr = pNew; /* Ensure that the expression now has an implicit collation sequence, ** just as it did when it was a column of a view or sub-query. */ if( pExpr ){ if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, (pColl ? pColl->zName : "BINARY") ); } ExprClearProperty(pExpr, EP_Collate); } } } }else{ if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){ pExpr->iTable = pSubst->iNewTable; } pExpr->pLeft = substExpr(pSubst, pExpr->pLeft); |
︙ | ︙ | |||
3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 | ** will scan expressions looking for iParent references and replace ** those references with expressions that resolve to the subquery FROM ** elements we are now copying in. */ for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ int nSubSrc; u8 jointype = 0; pSubSrc = pSub->pSrc; /* FROM clause of subquery */ nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ pSrc = pParent->pSrc; /* FROM clause of the outer query */ if( pSrc ){ assert( pParent==p ); /* First time through the loop */ jointype = pSubitem->fg.jointype; | > | 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 | ** will scan expressions looking for iParent references and replace ** those references with expressions that resolve to the subquery FROM ** elements we are now copying in. */ for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ int nSubSrc; u8 jointype = 0; assert( pSub!=0 ); pSubSrc = pSub->pSrc; /* FROM clause of subquery */ nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ pSrc = pParent->pSrc; /* FROM clause of the outer query */ if( pSrc ){ assert( pParent==p ); /* First time through the loop */ jointype = pSubitem->fg.jointype; |
︙ | ︙ | |||
4395 4396 4397 4398 4399 4400 4401 | ** analysis. */ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */ const char *zFunc; /* Name of aggregate function pFunc */ ExprList *pOrderBy; | | > | > > | | | | 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 | ** analysis. */ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */ const char *zFunc; /* Name of aggregate function pFunc */ ExprList *pOrderBy; u8 sortFlags; assert( *ppMinMax==0 ); assert( pFunc->op==TK_AGG_FUNCTION ); assert( !IsWindowFunc(pFunc) ); if( pEList==0 || pEList->nExpr!=1 || ExprHasProperty(pFunc, EP_WinFunc) ){ return eRet; } zFunc = pFunc->u.zToken; if( sqlite3StrICmp(zFunc, "min")==0 ){ eRet = WHERE_ORDERBY_MIN; sortFlags = KEYINFO_ORDER_BIGNULL; }else if( sqlite3StrICmp(zFunc, "max")==0 ){ eRet = WHERE_ORDERBY_MAX; sortFlags = KEYINFO_ORDER_DESC; }else{ return eRet; } *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0); assert( pOrderBy!=0 || db->mallocFailed ); if( pOrderBy ) pOrderBy->a[0].sortFlags = sortFlags; return eRet; } /* ** The select statement passed as the first argument is an aggregate query. ** The second argument is the associated aggregate-info object. This ** function tests if the SELECT is of the form: |
︙ | ︙ | |||
4446 4447 4448 4449 4450 4451 4452 | pExpr = p->pEList->a[0].pExpr; assert( pTab && !pTab->pSelect && pExpr ); if( IsVirtual(pTab) ) return 0; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; if( NEVER(pAggInfo->nFunc==0) ) return 0; if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0; | | | 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 | pExpr = p->pEList->a[0].pExpr; assert( pTab && !pTab->pSelect && pExpr ); if( IsVirtual(pTab) ) return 0; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; if( NEVER(pAggInfo->nFunc==0) ) return 0; if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0; if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0; return pTab; } /* ** If the source-list item passed as an argument was augmented with an ** INDEXED BY clause, then try to locate the specified index. If there |
︙ | ︙ | |||
4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 | } #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) if( IsVirtual(pTab) || pTab->pSelect ){ i16 nCol; u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); nCol = pTab->nCol; pTab->nCol = -1; pWalker->eCode = 1; /* Turn on Select.selId renumbering */ sqlite3WalkSelect(pWalker, pFrom->pSelect); pWalker->eCode = eCodeOrig; pTab->nCol = nCol; | > > > > | 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 | } #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) if( IsVirtual(pTab) || pTab->pSelect ){ i16 nCol; u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){ sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", pTab->zName); } pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); nCol = pTab->nCol; pTab->nCol = -1; pWalker->eCode = 1; /* Turn on Select.selId renumbering */ sqlite3WalkSelect(pWalker, pFrom->pSelect); pWalker->eCode = eCodeOrig; pTab->nCol = nCol; |
︙ | ︙ | |||
5186 5187 5188 5189 5190 5191 5192 | Table *pTab = pFrom->pTab; assert( pTab!=0 ); if( (pTab->tabFlags & TF_Ephemeral)!=0 ){ /* A sub-query in the FROM clause of a SELECT */ Select *pSel = pFrom->pSelect; if( pSel ){ while( pSel->pPrior ) pSel = pSel->pPrior; | | > | 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 | Table *pTab = pFrom->pTab; assert( pTab!=0 ); if( (pTab->tabFlags & TF_Ephemeral)!=0 ){ /* A sub-query in the FROM clause of a SELECT */ Select *pSel = pFrom->pSelect; if( pSel ){ while( pSel->pPrior ) pSel = pSel->pPrior; sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel, SQLITE_AFF_NONE); } } } } #endif |
︙ | ︙ | |||
5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 | pAggInfo->directMode = 1; for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ int nArg; int addrNext = 0; int regAgg; ExprList *pList = pF->pExpr->x.pList; assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP); }else{ nArg = 0; regAgg = 0; } if( pF->iDistinct>=0 ){ | > > > > > > > | > | 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 | pAggInfo->directMode = 1; for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ int nArg; int addrNext = 0; int regAgg; ExprList *pList = pF->pExpr->x.pList; assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); assert( !IsWindowFunc(pF->pExpr) ); if( ExprHasProperty(pF->pExpr, EP_WinFunc) ){ Expr *pFilter = pF->pExpr->y.pWin->pFilter; addrNext = sqlite3VdbeMakeLabel(pParse); sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL); } if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP); }else{ nArg = 0; regAgg = 0; } if( pF->iDistinct>=0 ){ if( addrNext==0 ){ addrNext = sqlite3VdbeMakeLabel(pParse); } testcase( nArg==0 ); /* Error condition */ testcase( nArg>1 ); /* Also an error */ codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg); } if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ CollSeq *pColl = 0; struct ExprList_item *pItem; |
︙ | ︙ | |||
5838 5839 5840 5841 5842 5843 5844 | ** have a column named by the empty string, in which case there is no way to ** distinguish between an unreferenced table and an actual reference to the ** "" column. The original design was for the fake column name to be a NULL, ** which would be unambiguous. But legacy authorization callbacks might ** assume the column name is non-NULL and segfault. The use of an empty ** string for the fake column name seems safer. */ | | | > > > > > > > | | 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 | ** have a column named by the empty string, in which case there is no way to ** distinguish between an unreferenced table and an actual reference to the ** "" column. The original design was for the fake column name to be a NULL, ** which would be unambiguous. But legacy authorization callbacks might ** assume the column name is non-NULL and segfault. The use of an empty ** string for the fake column name seems safer. */ if( pItem->colUsed==0 && pItem->zName!=0 ){ sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase); } #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* Generate code for all sub-queries in the FROM clause */ pSub = pItem->pSelect; if( pSub==0 ) continue; /* The code for a subquery should only be generated once, though it is ** technically harmless for it to be generated multiple times. The ** following assert() will detect if something changes to cause ** the same subquery to be coded multiple times, as a signal to the ** developers to try to optimize the situation. ** ** Update 2019-07-24: ** See ticket https://sqlite.org/src/tktview/c52b09c7f38903b1311cec40. ** The dbsqlfuzz fuzzer found a case where the same subquery gets ** coded twice. So this assert() now becomes a testcase(). It should ** be very rare, though. */ testcase( pItem->addrFillSub!=0 ); /* Increment Parse.nHeight by the height of the largest expression ** tree referred to by this, the parent select. The child select ** may contain expression trees of at most ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit ** more conservative than necessary, but much easier than enforcing ** an exact limit. |
︙ | ︙ | |||
5927 5928 5929 5930 5931 5932 5933 | ** is a register allocated to hold the subroutine return address */ int topAddr; int onceAddr = 0; int retAddr; struct SrcList_item *pPrior; | | | 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 | ** is a register allocated to hold the subroutine return address */ int topAddr; int onceAddr = 0; int retAddr; struct SrcList_item *pPrior; testcase( pItem->addrFillSub==0 ); /* Ticket c52b09c7f38903b1311 */ pItem->regReturn = ++pParse->nMem; topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); pItem->addrFillSub = topAddr+1; if( pItem->fg.isCorrelated==0 ){ /* If the subquery is not correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ |
︙ | ︙ | |||
6218 6219 6220 6221 6222 6223 6224 | sAggInfo.nAccumulator = sAggInfo.nColumn; if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){ minMaxFlag = minMaxQuery(db, sAggInfo.aFunc[0].pExpr, &pMinMaxOrderBy); }else{ minMaxFlag = WHERE_ORDERBY_NORMAL; } for(i=0; i<sAggInfo.nFunc; i++){ | > | | > > > > > > | 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 | sAggInfo.nAccumulator = sAggInfo.nColumn; if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){ minMaxFlag = minMaxQuery(db, sAggInfo.aFunc[0].pExpr, &pMinMaxOrderBy); }else{ minMaxFlag = WHERE_ORDERBY_NORMAL; } for(i=0; i<sAggInfo.nFunc; i++){ Expr *pExpr = sAggInfo.aFunc[i].pExpr; assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); sNC.ncFlags |= NC_InAggFunc; sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList); #ifndef SQLITE_OMIT_WINDOWFUNC assert( !IsWindowFunc(pExpr) ); if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3ExprAnalyzeAggregates(&sNC, pExpr->y.pWin->pFilter); } #endif sNC.ncFlags &= ~NC_InAggFunc; } sAggInfo.mxReg = pParse->nMem; if( db->mallocFailed ) goto select_end; #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x400 ){ int ii; |
︙ | ︙ |
Changes to src/shell.c.in.
︙ | ︙ | |||
1252 1253 1254 1255 1256 1257 1258 | 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 ){ | | | | 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 | f = fopen(zTempFile, bBin ? "wb" : "w"); if( f==0 ){ sqlite3_result_error(context, "edit() cannot open temp file", -1); goto edit_func_end; } sz = sqlite3_value_bytes(argv[0]); if( bBin ){ x = fwrite(sqlite3_value_blob(argv[0]), 1, (size_t)sz, f); }else{ const char *z = (const char*)sqlite3_value_text(argv[0]); /* Remember whether or not the value originally contained \r\n */ if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1; x = fwrite(sqlite3_value_text(argv[0]), 1, (size_t)sz, f); } fclose(f); f = 0; if( x!=sz ){ sqlite3_result_error(context, "edit() could not write the whole file", -1); goto edit_func_end; } |
︙ | ︙ | |||
1285 1286 1287 1288 1289 1290 1291 | 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); | | | | 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 | sqlite3_result_error(context, "edit() cannot reopen temp file after edit", -1); goto edit_func_end; } fseek(f, 0, SEEK_END); sz = ftell(f); rewind(f); p = sqlite3_malloc64( sz+1 ); if( p==0 ){ sqlite3_result_error_nomem(context); goto edit_func_end; } x = fread(p, 1, (size_t)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 ){ |
︙ | ︙ | |||
1762 1763 1764 1765 1766 1767 1768 | 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; | | > | 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 | 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; } } } |
︙ | ︙ | |||
1953 1954 1955 1956 1957 1958 1959 | j--; } z[j++] = c; } while( j>0 && IsSpace(z[j-1]) ){ j--; } z[j] = 0; if( strlen30(z)>=79 ){ | | | 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 | j--; } z[j++] = c; } while( j>0 && IsSpace(z[j-1]) ){ j--; } z[j] = 0; if( strlen30(z)>=79 ){ for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */ if( c==cEnd ){ cEnd = 0; }else if( c=='"' || c=='\'' || c=='`' ){ cEnd = c; }else if( c=='[' ){ cEnd = ']'; }else if( c=='-' && z[i+1]=='-' ){ |
︙ | ︙ | |||
2532 2533 2534 2535 2536 2537 2538 | 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); | | | 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 | raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); raw_printf(pArg->out, "Sort Operations: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset); 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); } |
︙ | ︙ | |||
3455 3456 3457 3458 3459 3460 3461 | ** start of the description of what that command does. */ static const char *(azHelp[]) = { #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) ".archive ... Manage SQL archives", " Each command must have exactly one of the following options:", " -c, --create Create a new archive", | | | | | | | | | | | | | | | | 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 | ** start of the description of what that command does. */ static const char *(azHelp[]) = { #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) ".archive ... Manage SQL archives", " Each command must have exactly one of the following options:", " -c, --create Create a new archive", " -u, --update Add or update files with changed mtime", " -i, --insert Like -u but always add even if unchanged", " -t, --list List contents of archive", " -x, --extract Extract files from archive", " Optional arguments:", " -v, --verbose Print each filename as it is processed", " -f FILE, --file FILE Use archive FILE (default is current db)", " -a FILE, --append FILE Open FILE using the apndvfs VFS", " -C DIR, --directory DIR Read/extract files from directory DIR", " -n, --dryrun Show the SQL that would have occurred", " Examples:", " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar", " .ar -tf ARCHIVE # List members of ARCHIVE", " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE", " See also:", " http://sqlite.org/cli.html#sqlar_archive_support", #endif #ifndef SQLITE_OMIT_AUTHORIZATION ".auth ON|OFF Show authorizer callbacks", #endif ".backup ?DB? FILE Backup DB (default \"main\") to FILE", " --append Use the appendvfs", " --async Write to FILE without journal and fsync()", ".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 a 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", " Other Modes:", #ifdef SQLITE_DEBUG " test Show raw EXPLAIN QUERY PLAN output", " trace Like \"full\" but enable \"PRAGMA vdbe_trace\"", #endif " trigger Like \"full\" but also show trigger bytecode", ".excel Display the output of next command in spreadsheet", ".exit ?CODE? Exit this program with return-code CODE", ".expert EXPERIMENTAL. Suggest indexes for 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",*/ ".filectrl CMD ... Run various sqlite3_file_control() operations", " Run \".filectrl\" with no arguments for details", ".fullschema ?--indent? Show schema and the content of sqlite_stat tables", ".headers on|off Turn display of headers on or off", ".help ?-all? ?PATTERN? Show help text for PATTERN", ".import FILE TABLE Import data from FILE into TABLE", #ifndef SQLITE_OMIT_TEST_CONTROL |
︙ | ︙ | |||
3552 3553 3554 3555 3556 3557 3558 | " -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", #ifdef SQLITE_ENABLE_DESERIALIZE " --deserialize Load into memory useing sqlite3_deserialize()", | | | > > > > > | 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 | " -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", #ifdef SQLITE_ENABLE_DESERIALIZE " --deserialize Load into memory useing sqlite3_deserialize()", " --hexdb Load the output of \"dbtotxt\" as an in-memory db", " --maxsize N Maximum size for --hexdb or --deserialized database", #endif " --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.", ".parameter CMD ... Manage SQL parameter bindings", " clear Erase all bindings", " init Initialize the TEMP table that holds bindings", " list List the current parameter bindings", " set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE", " PARAMETER should start with one of: $ : @ ?", " unset PARAMETER Remove PARAMETER from the binding table", ".print STRING... Print literal STRING", #ifndef SQLITE_OMIT_PROGRESS_CALLBACK ".progress N Invoke progress handler after every N opcodes", " --limit N Interrupt after N progress callbacks", " --once Do no more than one progress interrupt", " --quiet|-q No output except at interrupts", " --reset Reset the count for each input and interrupt", #endif ".prompt MAIN CONTINUE Replace the standard prompts", ".quit Exit this program", ".read FILE Read input from FILE", #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) ".recover Recover as much data as possible from corrupt db.", " --freelist-corrupt Assume the freelist is corrupt", " --recovery-db NAME Store recovery metadata in database file NAME", " --lost-and-found TABLE Alternative name for the lost-and-found table", " --no-rowids Do not attempt to recover rowid values", " that are not also INTEGER PRIMARY KEYs", #endif ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE", ".save FILE Write in-memory database into FILE", ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off", ".schema ?PATTERN? Show the CREATE statements matching PATTERN", " Options:", " --indent Try to pretty-print the schema", |
︙ | ︙ | |||
3611 3612 3613 3614 3615 3616 3617 | " patchset FILE Write a patchset into FILE", " If ?NAME? is omitted, the first defined session is used.", #endif ".sha3sum ... Compute a SHA3 hash of database content", " Options:", " --schema Also hash the sqlite_master table", " --sha3-224 Use the sha3-224 algorithm", | | | 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 | " patchset FILE Write a patchset into FILE", " If ?NAME? is omitted, the first defined session is used.", #endif ".sha3sum ... Compute a SHA3 hash of database content", " Options:", " --schema Also hash the sqlite_master table", " --sha3-224 Use the sha3-224 algorithm", " --sha3-256 Use the sha3-256 algorithm (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", |
︙ | ︙ | |||
3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 | #endif " --plain Show SQL as it is input", " --stmt Trace statement execution (SQLITE_TRACE_STMT)", " --profile Profile statements (SQLITE_TRACE_PROFILE)", " --row Trace each row (SQLITE_TRACE_ROW)", " --close Trace connection close (SQLITE_TRACE_CLOSE)", #endif /* SQLITE_OMIT_TRACE */ ".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", }; | > > > > | 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 | #endif " --plain Show SQL as it is input", " --stmt Trace statement execution (SQLITE_TRACE_STMT)", " --profile Profile statements (SQLITE_TRACE_PROFILE)", " --row Trace each row (SQLITE_TRACE_ROW)", " --close Trace connection close (SQLITE_TRACE_CLOSE)", #endif /* SQLITE_OMIT_TRACE */ #ifdef SQLITE_DEBUG ".unmodule NAME ... Unregister virtual table modules", " --allexcept Unregister everything except those named", #endif ".vfsinfo ?AUX? Information about the top-level VFS", ".vfslist List all available VFSes", ".vfsname ?AUX? Print the name of the VFS stack", ".width NUM1 NUM2 ... Set column widths for \"column\" mode", " Negative values right-justify", }; |
︙ | ︙ | |||
3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 | } *pnData = 0; nLine++; if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); if( rc!=2 ) goto readHexDb_error; if( n<0 ) goto readHexDb_error; a = sqlite3_malloc( n ? n : 1 ); if( a==0 ){ utf8_printf(stderr, "Out of memory!\n"); goto readHexDb_error; } memset(a, 0, n); if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ | > > | 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 | } *pnData = 0; nLine++; if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); if( rc!=2 ) goto readHexDb_error; if( n<0 ) goto readHexDb_error; if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error; n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */ a = sqlite3_malloc( n ? n : 1 ); if( a==0 ){ utf8_printf(stderr, "Out of memory!\n"); goto readHexDb_error; } memset(a, 0, n); if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ |
︙ | ︙ | |||
3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 | sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24) + ((sqlite3_int64)a[1]<<16) + ((sqlite3_int64)a[2]<< 8) + ((sqlite3_int64)a[3]<< 0); sqlite3_result_int64(context, iVal); } } /* ** Scalar function "shell_escape_crnl" used by the .recover command. ** The argument passed to this function is the output of built-in ** function quote(). If the first character of the input is "'", ** indicating that the value passed to quote() was a text value, ** then this function searches the input for "\n" and "\r" characters | > > > > > > > > > > > > > > > > > | 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 | sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24) + ((sqlite3_int64)a[1]<<16) + ((sqlite3_int64)a[2]<< 8) + ((sqlite3_int64)a[3]<< 0); sqlite3_result_int64(context, iVal); } } /* ** Scalar function "shell_idquote(X)" returns string X quoted as an identifier, ** using "..." with internal double-quote characters doubled. */ static void shellIdQuote( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zName = (const char*)sqlite3_value_text(argv[0]); UNUSED_PARAMETER(argc); if( zName ){ char *z = sqlite3_mprintf("\"%w\"", zName); sqlite3_result_text(context, z, -1, sqlite3_free); } } /* ** Scalar function "shell_escape_crnl" used by the .recover command. ** The argument passed to this function is the output of built-in ** function quote(). If the first character of the input is "'", ** indicating that the value passed to quote() was a text value, ** then this function searches the input for "\n" and "\r" characters |
︙ | ︙ | |||
4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 | shellModuleSchema, 0, 0); sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p, shellPutsFunc, 0, 0); sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0, shellEscapeCrnl, 0, 0); sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0, shellInt32, 0, 0); #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 ){ | > > | 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 | shellModuleSchema, 0, 0); sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p, shellPutsFunc, 0, 0); sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0, shellEscapeCrnl, 0, 0); sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0, shellInt32, 0, 0); sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0, shellIdQuote, 0, 0); #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 ){ |
︙ | ︙ | |||
5494 5495 5496 5497 5498 5499 5500 | } *pRc = rc; } } #endif /* !defined SQLITE_OMIT_VIRTUALTABLE */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) | | | 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 | } *pRc = rc; } } #endif /* !defined SQLITE_OMIT_VIRTUALTABLE */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) /****************************************************************************** ** The ".archive" or ".ar" command. */ /* ** Structure representing a single ".ar" command. */ typedef struct ArCommand ArCommand; struct ArCommand { |
︙ | ︙ | |||
5692 5693 5694 5695 5696 5697 5698 | } if( pOpt->bArg ){ if( i<(n-1) ){ zArg = &z[i+1]; i = n; }else{ if( iArg>=(nArg-1) ){ | | > | 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 | } 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' ){ |
︙ | ︙ | |||
6080 6081 6082 6083 6084 6085 6086 | return rc; } /* ** Implementation of ".ar" dot command. */ static int arDotCommand( | | | | | | 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 | 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 ){ |
︙ | ︙ | |||
6183 6184 6185 6186 6187 6188 6189 | close_db(cmd.db); } sqlite3_free(cmd.zSrcTable); return rc; } /* End of the ".archive" or ".ar" command logic | | | 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 | close_db(cmd.db); } sqlite3_free(cmd.zSrcTable); return rc; } /* End of the ".archive" or ".ar" command logic *******************************************************************************/ #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) /* ** If (*pRc) is not SQLITE_OK when this function is called, it is a no-op. ** Otherwise, the SQL statement or statements in zSql are executed using ** database connection db and the error code written to *pRc before |
︙ | ︙ | |||
6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 | pTab = (RecoverTable*)shellMalloc(&rc, sizeof(RecoverTable)); if( rc==SQLITE_OK ){ int nSqlCol = 0; int bSqlIntkey = 0; sqlite3_stmt *pStmt = 0; rc = sqlite3_open("", &dbtmp); if( rc==SQLITE_OK ){ rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0); } if( rc==SQLITE_OK ){ rc = sqlite3_exec(dbtmp, zSql, 0, 0, 0); if( rc==SQLITE_ERROR ){ rc = SQLITE_OK; | > > > > | 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 | pTab = (RecoverTable*)shellMalloc(&rc, sizeof(RecoverTable)); if( rc==SQLITE_OK ){ int nSqlCol = 0; int bSqlIntkey = 0; sqlite3_stmt *pStmt = 0; rc = sqlite3_open("", &dbtmp); if( rc==SQLITE_OK ){ sqlite3_create_function(dbtmp, "shell_idquote", 1, SQLITE_UTF8, 0, shellIdQuote, 0, 0); } if( rc==SQLITE_OK ){ rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0); } if( rc==SQLITE_OK ){ rc = sqlite3_exec(dbtmp, zSql, 0, 0, 0); if( rc==SQLITE_ERROR ){ rc = SQLITE_OK; |
︙ | ︙ | |||
6380 6381 6382 6383 6384 6385 6386 | ); if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPkFinder) ){ pTab->iPk = sqlite3_column_int(pPkFinder, 0); zPk = (const char*)sqlite3_column_text(pPkFinder, 1); } } | | | | | 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 | ); if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPkFinder) ){ pTab->iPk = sqlite3_column_int(pPkFinder, 0); zPk = (const char*)sqlite3_column_text(pPkFinder, 1); } } pTab->zQuoted = shellMPrintf(&rc, "\"%w\"", zName); pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1)); pTab->nCol = nSqlCol; if( bIntkey ){ pTab->azlCol[0] = shellMPrintf(&rc, "\"%w\"", zPk); }else{ pTab->azlCol[0] = shellMPrintf(&rc, ""); } i = 1; shellPreparePrintf(dbtmp, &rc, &pStmt, "SELECT %Q || group_concat(shell_idquote(name), ', ') " " FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) " "FROM pragma_table_info(%Q)", bIntkey ? ", " : "", pTab->iPk, bIntkey ? "" : "(CASE WHEN pk=0 THEN 1000000 ELSE pk END), ", zName ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ |
︙ | ︙ | |||
6505 6506 6507 6508 6509 6510 6511 | zTab = shellMPrintf(pRc, "%s_%d", zLostAndFound, iTab++); sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT); } shellFinalize(pRc, pTest); pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable)); if( pTab ){ | | | 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 | zTab = shellMPrintf(pRc, "%s_%d", zLostAndFound, iTab++); sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT); } shellFinalize(pRc, pTest); pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable)); if( pTab ){ pTab->zQuoted = shellMPrintf(pRc, "\"%w\"", zTab); pTab->nCol = nCol; pTab->iPk = -2; if( nCol>0 ){ pTab->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * (nCol+1)); if( pTab->azlCol ){ pTab->azlCol[nCol] = shellMPrintf(pRc, ""); for(i=nCol-1; i>=0; i--){ |
︙ | ︙ | |||
6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 | const char *zRecoveryDb = ""; /* Name of "recovery" database */ const char *zLostAndFound = "lost_and_found"; int i; int nOrphan = -1; RecoverTable *pOrphan = 0; int bFreelist = 1; /* 0 if --freelist-corrupt is specified */ for(i=1; i<nArg; i++){ char *z = azArg[i]; int n; if( z[0]=='-' && z[1]=='-' ) z++; n = strlen30(z); if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){ bFreelist = 0; }else if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){ i++; zRecoveryDb = azArg[i]; }else if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){ i++; zLostAndFound = azArg[i]; } else{ | > > > > | < < < | > | 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 | const char *zRecoveryDb = ""; /* Name of "recovery" database */ const char *zLostAndFound = "lost_and_found"; int i; int nOrphan = -1; RecoverTable *pOrphan = 0; int bFreelist = 1; /* 0 if --freelist-corrupt is specified */ int bRowids = 1; /* 0 if --no-rowids */ for(i=1; i<nArg; i++){ char *z = azArg[i]; int n; if( z[0]=='-' && z[1]=='-' ) z++; n = strlen30(z); if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){ bFreelist = 0; }else if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){ i++; zRecoveryDb = azArg[i]; }else if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){ i++; zLostAndFound = azArg[i]; }else if( n<=10 && memcmp("-no-rowids", z, n)==0 ){ bRowids = 0; } else{ utf8_printf(stderr, "unexpected option: %s\n", azArg[i]); showHelp(pState->out, azArg[0]); return 1; } } shellExecPrintf(pState->db, &rc, /* Attach an in-memory database named 'recovery'. Create an indexed ** cache of the sqlite_dbptr virtual table. */ "PRAGMA writable_schema = on;" "ATTACH %Q AS recovery;" "DROP TABLE IF EXISTS recovery.dbptr;" "DROP TABLE IF EXISTS recovery.freelist;" "DROP TABLE IF EXISTS recovery.map;" "DROP TABLE IF EXISTS recovery.schema;" "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);", zRecoveryDb ); |
︙ | ︙ | |||
6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 | " UNION ALL" " SELECT data, n-1, shell_int32(data, 2+n) " " FROM freelist WHERE n>=0" ")" "REPLACE INTO recovery.freelist SELECT freepgno FROM freelist;" ); } shellExec(pState->db, &rc, "CREATE TABLE recovery.dbptr(" " pgno, child, PRIMARY KEY(child, pgno)" ") WITHOUT ROWID;" "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) " " SELECT * FROM sqlite_dbptr" | > > > > > > > > > > > > > > > | 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 | " UNION ALL" " SELECT data, n-1, shell_int32(data, 2+n) " " FROM freelist WHERE n>=0" ")" "REPLACE INTO recovery.freelist SELECT freepgno FROM freelist;" ); } /* If this is an auto-vacuum database, add all pointer-map pages to ** the freelist table. Do this regardless of whether or not ** --freelist-corrupt was specified. */ shellExec(pState->db, &rc, "WITH ptrmap(pgno) AS (" " SELECT 2 WHERE shell_int32(" " (SELECT data FROM sqlite_dbpage WHERE pgno=1), 13" " )" " UNION ALL " " SELECT pgno+1+(SELECT page_size FROM pragma_page_size)/5 AS pp " " FROM ptrmap WHERE pp<=(SELECT page_count FROM pragma_page_count)" ")" "REPLACE INTO recovery.freelist SELECT pgno FROM ptrmap" ); shellExec(pState->db, &rc, "CREATE TABLE recovery.dbptr(" " pgno, child, PRIMARY KEY(child, pgno)" ") WITHOUT ROWID;" "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) " " SELECT * FROM sqlite_dbptr" |
︙ | ︙ | |||
6661 6662 6663 6664 6665 6666 6667 | " SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)" " UNION " " SELECT i, p.parent, " " (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p" " )" " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)" ") " | | | 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 | " SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)" " UNION " " SELECT i, p.parent, " " (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p" " )" " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)" ") " "FROM pages WHERE maxlen IS NOT NULL AND i NOT IN freelist;" "UPDATE recovery.map AS o SET intkey = (" " SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno" ");" /* Extract data from page 1 and any linked pages into table ** recovery.schema. With the same schema as an sqlite_master table. */ "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);" |
︙ | ︙ | |||
6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 | "CREATE INDEX recovery.schema_rootpage ON schema(rootpage);" ); /* Open a transaction, then print out all non-virtual, non-"sqlite_%" ** CREATE TABLE statements that extracted from the existing schema. */ if( rc==SQLITE_OK ){ sqlite3_stmt *pStmt = 0; raw_printf(pState->out, "BEGIN;\n"); raw_printf(pState->out, "PRAGMA writable_schema = on;\n"); shellPrepare(pState->db, &rc, "SELECT sql FROM recovery.schema " "WHERE type='table' AND sql LIKE 'create table%'", &pStmt ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ | > > > > > | 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 | "CREATE INDEX recovery.schema_rootpage ON schema(rootpage);" ); /* Open a transaction, then print out all non-virtual, non-"sqlite_%" ** CREATE TABLE statements that extracted from the existing schema. */ if( rc==SQLITE_OK ){ sqlite3_stmt *pStmt = 0; /* ".recover" might output content in an order which causes immediate ** foreign key constraints to be violated. So disable foreign-key ** constraint enforcement to prevent problems when running the output ** script. */ raw_printf(pState->out, "PRAGMA foreign_keys=OFF;\n"); raw_printf(pState->out, "BEGIN;\n"); raw_printf(pState->out, "PRAGMA writable_schema = on;\n"); shellPrepare(pState->db, &rc, "SELECT sql FROM recovery.schema " "WHERE type='table' AND sql LIKE 'create table%'", &pStmt ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ |
︙ | ︙ | |||
6716 6717 6718 6719 6720 6721 6722 6723 | } shellFinalize(&rc, pLoop); pLoop = 0; shellPrepare(pState->db, &rc, "SELECT pgno FROM recovery.map WHERE root=?", &pPages ); shellPrepare(pState->db, &rc, | > | > > > > | > > > > > | | > > > > > > > > > > | | | | | 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 | } shellFinalize(&rc, pLoop); pLoop = 0; shellPrepare(pState->db, &rc, "SELECT pgno FROM recovery.map WHERE root=?", &pPages ); shellPrepare(pState->db, &rc, "SELECT max(field), group_concat(shell_escape_crnl(quote" "(case when (? AND field<0) then NULL else value end)" "), ', ')" ", min(field) " "FROM sqlite_dbdata WHERE pgno = ? AND field != ?" "GROUP BY cell", &pCells ); /* Loop through each root page. */ shellPrepare(pState->db, &rc, "SELECT root, intkey, max(maxlen) FROM recovery.map" " WHERE root>1 GROUP BY root, intkey ORDER BY root=(" " SELECT rootpage FROM recovery.schema WHERE name='sqlite_sequence'" ")", &pLoop ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){ int iRoot = sqlite3_column_int(pLoop, 0); int bIntkey = sqlite3_column_int(pLoop, 1); int nCol = sqlite3_column_int(pLoop, 2); int bNoop = 0; RecoverTable *pTab; assert( bIntkey==0 || bIntkey==1 ); pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop); if( bNoop || rc ) continue; if( pTab==0 ){ if( pOrphan==0 ){ pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan); } pTab = pOrphan; if( pTab==0 ) break; } if( 0==sqlite3_stricmp(pTab->zQuoted, "\"sqlite_sequence\"") ){ raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n"); } sqlite3_bind_int(pPages, 1, iRoot); if( bRowids==0 && pTab->iPk<0 ){ sqlite3_bind_int(pCells, 1, 1); }else{ sqlite3_bind_int(pCells, 1, 0); } sqlite3_bind_int(pCells, 3, pTab->iPk); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){ int iPgno = sqlite3_column_int(pPages, 0); sqlite3_bind_int(pCells, 2, iPgno); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){ int nField = sqlite3_column_int(pCells, 0); int iMin = sqlite3_column_int(pCells, 2); const char *zVal = (const char*)sqlite3_column_text(pCells, 1); RecoverTable *pTab2 = pTab; if( pTab!=pOrphan && (iMin<0)!=bIntkey ){ if( pOrphan==0 ){ pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan); } pTab2 = pOrphan; if( pTab2==0 ) break; } nField = nField+1; if( pTab2==pOrphan ){ raw_printf(pState->out, "INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n", pTab2->zQuoted, iRoot, iPgno, nField, iMin<0 ? "" : "NULL, ", zVal, pTab2->azlCol[nField] ); }else{ raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n", pTab2->zQuoted, pTab2->azlCol[nField], zVal ); } } shellReset(&rc, pCells); } shellReset(&rc, pPages); if( pTab!=pOrphan ) recoverFreeTable(pTab); |
︙ | ︙ | |||
6827 6828 6829 6830 6831 6832 6833 | ** 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; | | | > | 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 | ** Return 1 on error, 2 to exit, and 0 otherwise. */ static int do_meta_command(char *zLine, ShellState *p){ int h = 1; int nArg = 0; int n, c; int rc = 0; char *azArg[52]; #ifndef SQLITE_OMIT_VIRTUALTABLE if( p->expert.pExpert ){ expertFinish(p, 1, 0); } #endif /* Parse the input line into tokens. */ while( zLine[h] && nArg<ArraySize(azArg)-1 ){ while( IsSpace(zLine[h]) ){ h++; } if( zLine[h]==0 ) break; if( zLine[h]=='\'' || zLine[h]=='"' ){ int delim = zLine[h++]; azArg[nArg++] = &zLine[h]; while( zLine[h] && zLine[h]!=delim ){ if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++; h++; } if( zLine[h]==delim ){ zLine[h++] = 0; } if( delim=='"' ) resolve_backslashes(azArg[nArg-1]); }else{ azArg[nArg++] = &zLine[h]; while( zLine[h] && !IsSpace(zLine[h]) ){ h++; } if( zLine[h] ) zLine[h++] = 0; resolve_backslashes(azArg[nArg-1]); } } azArg[nArg] = 0; /* Process the input line. */ if( nArg==0 ) return 0; /* no tokens, no error */ n = strlen30(azArg[0]); c = azArg[0][0]; clearTempFile(p); |
︙ | ︙ | |||
7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 | 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 }, { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, | > | 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 | 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 }, { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, { "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 }, { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, |
︙ | ︙ | |||
7446 7447 7448 7449 7450 7451 7452 | }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(&data, "SELECT * FROM sqlite_stat1", &zErrMsg); | < < | 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 | }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(&data, "SELECT * FROM sqlite_stat1", &zErrMsg); data.zDestTable = "sqlite_stat4"; shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg); raw_printf(p->out, "ANALYZE sqlite_master;\n"); } }else if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){ |
︙ | ︙ | |||
8384 8385 8386 8387 8388 8389 8390 | const char *zDb = (const char*)sqlite3_column_text(pStmt, 0); char zScNum[30]; sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema); appendText(&sSelect, zDiv, 0); zDiv = " UNION ALL "; appendText(&sSelect, "SELECT shell_add_schema(sql,", 0); if( sqlite3_stricmp(zDb, "main")!=0 ){ | | | | | > | 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 | const char *zDb = (const char*)sqlite3_column_text(pStmt, 0); char zScNum[30]; sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema); appendText(&sSelect, zDiv, 0); zDiv = " UNION ALL "; appendText(&sSelect, "SELECT shell_add_schema(sql,", 0); if( sqlite3_stricmp(zDb, "main")!=0 ){ appendText(&sSelect, zDb, '\''); }else{ appendText(&sSelect, "NULL", 0); } appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0); appendText(&sSelect, zScNum, 0); appendText(&sSelect, " AS snum, ", 0); appendText(&sSelect, zDb, '\''); appendText(&sSelect, " AS sname FROM ", 0); appendText(&sSelect, zDb, quoteChar(zDb)); appendText(&sSelect, ".sqlite_master", 0); } sqlite3_finalize(pStmt); #ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS if( zName ){ appendText(&sSelect, " UNION ALL SELECT shell_module_schema(name)," " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0); } #endif appendText(&sSelect, ") WHERE ", 0); if( zName ){ char *zQarg = sqlite3_mprintf("%Q", zName); int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 || strchr(zName, '[') != 0; |
︙ | ︙ | |||
8500 8501 8502 8503 8504 8505 8506 | */ 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 ){ | | > | 8579 8580 8581 8582 8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 | */ 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); |
︙ | ︙ | |||
8821 8822 8823 8824 8825 8826 8827 | }else if( strcmp(z,"debug")==0 ){ bDebug = 1; }else { utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); | | < | 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 | }else if( strcmp(z,"debug")==0 ){ bDebug = 1; }else { utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); showHelp(p->out, azArg[0]); rc = 1; goto meta_command_exit; } }else if( zLike ){ raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n"); rc = 1; goto meta_command_exit; |
︙ | ︙ | |||
8868 8869 8870 8871 8872 8873 8874 | " 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); | | < | 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 | " ORDER BY name;", 0); }else if( strcmp(zTab, "sqlite_sequence")==0 ){ appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence" " ORDER BY name;", 0); }else if( strcmp(zTab, "sqlite_stat1")==0 ){ appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1" " ORDER BY tbl,idx;", 0); }else if( strcmp(zTab, "sqlite_stat4")==0 ){ 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; |
︙ | ︙ | |||
9101 9102 9103 9104 9105 9106 9107 | #ifndef SQLITE_UNTESTABLE if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){ static const struct { const char *zCtrlName; /* Name of a test-control option */ int ctrlCode; /* Integer code for that option */ const char *zUsage; /* Usage notes */ } aCtrl[] = { | | | | | | > | | | | | | | | < | | > | | 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 | #ifndef SQLITE_UNTESTABLE if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){ static const struct { const char *zCtrlName; /* Name of a test-control option */ int ctrlCode; /* Integer code for that option */ const char *zUsage; /* Usage notes */ } aCtrl[] = { { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" }, { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" }, /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/ /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/ { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" }, { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" }, /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" },*/ { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"}, { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" }, { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" }, { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" }, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" }, #ifdef YYCOVERAGE { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" }, #endif { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " }, { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" }, { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" }, { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" }, { "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE"}, }; int testctrl = -1; int iCtrl = -1; int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */ int isOk = 0; int i, n2; const char *zCmd = 0; |
︙ | ︙ | |||
9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 | case SQLITE_TESTCTRL_PENDING_BYTE: if( nArg==3 ){ unsigned int opt = (unsigned int)integerValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); isOk = 3; } break; /* sqlite3_test_control(int, int) */ case SQLITE_TESTCTRL_ASSERT: case SQLITE_TESTCTRL_ALWAYS: case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: if( nArg==3 ){ int opt = booleanValue(azArg[2]); | > > > > > > > > > > > > > > > > > > > > > | 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 | case SQLITE_TESTCTRL_PENDING_BYTE: if( nArg==3 ){ unsigned int opt = (unsigned int)integerValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); isOk = 3; } break; /* sqlite3_test_control(int, int, sqlite3*) */ case SQLITE_TESTCTRL_PRNG_SEED: if( nArg==3 || nArg==4 ){ int ii = (int)integerValue(azArg[2]); sqlite3 *db; if( ii==0 && strcmp(azArg[2],"random")==0 ){ sqlite3_randomness(sizeof(ii),&ii); printf("-- random seed: %d\n", ii); } if( nArg==3 ){ db = 0; }else{ db = p->db; /* Make sure the schema has been loaded */ sqlite3_table_column_metadata(db, 0, "x", 0, 0, 0, 0, 0, 0); } rc2 = sqlite3_test_control(testctrl, ii, db); isOk = 3; } break; /* sqlite3_test_control(int, int) */ case SQLITE_TESTCTRL_ASSERT: case SQLITE_TESTCTRL_ALWAYS: case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: if( nArg==3 ){ int opt = booleanValue(azArg[2]); |
︙ | ︙ | |||
9241 9242 9243 9244 9245 9246 9247 | sqlite3_test_control(testctrl, p->out); isOk = 3; } #endif } } if( isOk==0 && iCtrl>=0 ){ | | | 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 | 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 |
︙ | ︙ | |||
9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 | sqlite3_trace_v2(p->db, 0, 0, 0); }else{ if( mType==0 ) mType = SQLITE_TRACE_STMT; sqlite3_trace_v2(p->db, mType, sql_trace_callback, p); } }else #endif /* !defined(SQLITE_OMIT_TRACE) */ #if 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; } | > > > > > > > > > > > > > > > > > > > > > > > > > | > | 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 | sqlite3_trace_v2(p->db, 0, 0, 0); }else{ if( mType==0 ) mType = SQLITE_TRACE_STMT; sqlite3_trace_v2(p->db, mType, sql_trace_callback, p); } }else #endif /* !defined(SQLITE_OMIT_TRACE) */ #ifdef SQLITE_DEBUG if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){ int ii; int lenOpt; char *zOpt; if( nArg<2 ){ raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n"); rc = 1; goto meta_command_exit; } open_db(p, 0); zOpt = azArg[1]; if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++; lenOpt = (int)strlen(zOpt); if( lenOpt>=3 && strncmp(zOpt, "-allexcept",lenOpt)==0 ){ assert( azArg[nArg]==0 ); sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0); }else{ for(ii=1; ii<nArg; ii++){ sqlite3_create_module(p->db, azArg[ii], 0, 0); } } }else #endif #if SQLITE_USER_AUTHENTICATION if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ if( nArg<2 ){ raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n"); rc = 1; goto meta_command_exit; } open_db(p, 0); if( strcmp(azArg[1],"login")==0 ){ if( nArg!=4 ){ raw_printf(stderr, "Usage: .user login USER PASSWORD\n"); rc = 1; goto meta_command_exit; } rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], strlen30(azArg[3])); if( rc ){ utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]); rc = 1; } }else if( strcmp(azArg[1],"add")==0 ){ if( nArg!=5 ){ raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n"); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 | ** The first argument is an integer which is 0 to disable triggers, ** positive to enable triggers or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> ** <dd> ^This option is used to enable or disable the ** [fts3_tokenizer()] function which is part of the ** [FTS3] full-text search engine extension. ** There should be two additional arguments. ** The first argument is an integer which is 0 to disable fts3_tokenizer() or | > > > > > > > > > > > | 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 | ** The first argument is an integer which is 0 to disable triggers, ** positive to enable triggers or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] ** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt> ** <dd> ^This option is used to enable or disable [CREATE VIEW | views]. ** There should be two additional arguments. ** The first argument is an integer which is 0 to disable views, ** positive to enable views or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the view setting is not reported back. </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> ** <dd> ^This option is used to enable or disable the ** [fts3_tokenizer()] function which is part of the ** [FTS3] full-text search engine extension. ** There should be two additional arguments. ** The first argument is an integer which is 0 to disable fts3_tokenizer() or |
︙ | ︙ | |||
2261 2262 2263 2264 2265 2266 2267 | #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */ #define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */ #define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */ #define SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */ #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ | > | | 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 | #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */ #define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */ #define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */ #define SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */ #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_MAX 1015 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes ** METHOD: sqlite3 ** ** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result |
︙ | ︙ | |||
3810 3811 3812 3813 3814 3815 3816 | ** WHERE clause might influence the choice of query plan for a statement, ** then the statement will be automatically recompiled, as if there had been ** a schema change, on the first [sqlite3_step()] call following any change ** to the [sqlite3_bind_text | bindings] of that [parameter]. ** ^The specific value of WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column | | | 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 | ** WHERE clause might influence the choice of query plan for a statement, ** then the statement will be automatically recompiled, as if there had been ** a schema change, on the first [sqlite3_step()] call following any change ** to the [sqlite3_bind_text | bindings] of that [parameter]. ** ^The specific value of WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled. ** </li> ** </ol> ** ** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having ** the extra prepFlags parameter, which is a bit array consisting of zero or ** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The ** sqlite3_prepare_v2() interface works exactly the same as |
︙ | ︙ | |||
4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 | ** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC] ** to signal that the function will always return the same result given ** the same inputs within a single SQL statement. Most SQL functions are ** deterministic. The built-in [random()] SQL function is an example of a ** function that is not deterministic. The SQLite query planner is able to ** perform additional optimizations on deterministic functions, so use ** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ ** ** ^The sixth, seventh and eighth parameters passed to the three ** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are ** pointers to C-language functions that implement the SQL function or | > > > | 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 | ** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC] ** to signal that the function will always return the same result given ** the same inputs within a single SQL statement. Most SQL functions are ** deterministic. The built-in [random()] SQL function is an example of a ** function that is not deterministic. The SQLite query planner is able to ** perform additional optimizations on deterministic functions, so use ** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. ** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY] ** flag, which if present prevents the function from being invoked from ** within VIEWs or TRIGGERs. ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ ** ** ^The sixth, seventh and eighth parameters passed to the three ** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are ** pointers to C-language functions that implement the SQL function or |
︙ | ︙ | |||
4961 4962 4963 4964 4965 4966 4967 4968 | /* ** CAPI3REF: Function Flags ** ** These constants may be ORed together with the ** [SQLITE_UTF8 | preferred text encoding] as the fourth argument ** to [sqlite3_create_function()], [sqlite3_create_function16()], or ** [sqlite3_create_function_v2()]. */ | > > > > > > > > > > > > > > > | > > | 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 | /* ** CAPI3REF: Function Flags ** ** These constants may be ORed together with the ** [SQLITE_UTF8 | preferred text encoding] as the fourth argument ** to [sqlite3_create_function()], [sqlite3_create_function16()], or ** [sqlite3_create_function_v2()]. ** ** The SQLITE_DETERMINISTIC flag means that the new function will always ** maps the same inputs into the same output. The abs() function is ** deterministic, for example, but randomblob() is not. ** ** The SQLITE_DIRECTONLY flag means that the function may only be invoked ** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. ** ** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. ** Specifying this flag makes no difference for scalar or aggregate user ** functions. However, if it is not specified for a user-defined window ** function, then any sub-types belonging to arguments passed to the window ** function may be discarded before the window function is called (i.e. ** sqlite3_value_subtype() will always return 0). */ #define SQLITE_DETERMINISTIC 0x000000800 #define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_SUBTYPE 0x000100000 /* ** CAPI3REF: Deprecated Functions ** DEPRECATED ** ** These functions are [deprecated]. In order to maintain ** backwards compatibility with older code, these functions continue |
︙ | ︙ | |||
6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 | ** is a pointer to a destructor for the pClientData. ^SQLite will ** invoke the destructor function (if it is not NULL) when SQLite ** no longer needs the pClientData pointer. ^The destructor will also ** be invoked if the call to sqlite3_create_module_v2() fails. ** ^The sqlite3_create_module() ** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. */ int sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData /* Client data for xCreate/xConnect */ ); int sqlite3_create_module_v2( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData, /* Client data for xCreate/xConnect */ void(*xDestroy)(void*) /* Module destructor function */ ); /* ** CAPI3REF: Virtual Table Instance Object ** KEYWORDS: sqlite3_vtab ** ** Every [virtual table module] implementation uses a subclass ** of this object to describe a particular instance | > > > > > > > > > > > > > > > > > > > > > > > | 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 | ** is a pointer to a destructor for the pClientData. ^SQLite will ** invoke the destructor function (if it is not NULL) when SQLite ** no longer needs the pClientData pointer. ^The destructor will also ** be invoked if the call to sqlite3_create_module_v2() fails. ** ^The sqlite3_create_module() ** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. ** ** ^If the third parameter (the pointer to the sqlite3_module object) is ** NULL then no new module is create and any existing modules with the ** same name are dropped. ** ** See also: [sqlite3_drop_modules()] */ int sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData /* Client data for xCreate/xConnect */ ); int sqlite3_create_module_v2( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData, /* Client data for xCreate/xConnect */ void(*xDestroy)(void*) /* Module destructor function */ ); /* ** CAPI3REF: Remove Unnecessary Virtual Table Implementations ** METHOD: sqlite3 ** ** ^The sqlite3_drop_modules(D,L) interface removes all virtual ** table modules from database connection D except those named on list L. ** The L parameter must be either NULL or a pointer to an array of pointers ** to strings where the array is terminated by a single NULL pointer. ** ^If the L parameter is NULL, then all virtual table modules are removed. ** ** See also: [sqlite3_create_module()] */ int sqlite3_drop_modules( sqlite3 *db, /* Remove modules from this connection */ const char **azKeep /* Except, do not remove the ones named here */ ); /* ** CAPI3REF: Virtual Table Instance Object ** KEYWORDS: sqlite3_vtab ** ** Every [virtual table module] implementation uses a subclass ** of this object to describe a particular instance |
︙ | ︙ | |||
7331 7332 7333 7334 7335 7336 7337 | ** without notice. These values are for testing purposes only. ** Applications should not use any of these parameters or the ** [sqlite3_test_control()] interface. */ #define SQLITE_TESTCTRL_FIRST 5 #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 | | | 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 | ** without notice. These values are for testing purposes only. ** Applications should not use any of these parameters or the ** [sqlite3_test_control()] interface. */ #define SQLITE_TESTCTRL_FIRST 5 #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */ #define SQLITE_TESTCTRL_BITVEC_TEST 8 #define SQLITE_TESTCTRL_FAULT_INSTALL 9 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 #define SQLITE_TESTCTRL_PENDING_BYTE 11 #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 |
︙ | ︙ | |||
7354 7355 7356 7357 7358 7359 7360 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 #define SQLITE_TESTCTRL_BYTEORDER 22 #define SQLITE_TESTCTRL_ISINIT 23 #define SQLITE_TESTCTRL_SORTER_MMAP 24 #define SQLITE_TESTCTRL_IMPOSTER 25 #define SQLITE_TESTCTRL_PARSER_COVERAGE 26 #define SQLITE_TESTCTRL_RESULT_INTREAL 27 | > > | | 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 #define SQLITE_TESTCTRL_BYTEORDER 22 #define SQLITE_TESTCTRL_ISINIT 23 #define SQLITE_TESTCTRL_SORTER_MMAP 24 #define SQLITE_TESTCTRL_IMPOSTER 25 #define SQLITE_TESTCTRL_PARSER_COVERAGE 26 #define SQLITE_TESTCTRL_RESULT_INTREAL 27 #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking ** ** These routines provide access to the set of SQL language keywords ** recognized by SQLite. Applications can uses these routines to determine ** whether or not a specific identifier needs to be escaped (for example, |
︙ | ︙ |
Changes to src/sqlite3ext.h.
︙ | ︙ | |||
318 319 320 321 322 323 324 325 326 327 328 329 330 331 | void (*xInv)(sqlite3_context*,int,sqlite3_value**), void(*xDestroy)(void*)); /* Version 3.26.0 and later */ const char *(*normalized_sql)(sqlite3_stmt*); /* Version 3.28.0 and later */ int (*stmt_isexplain)(sqlite3_stmt*); int (*value_frombind)(sqlite3_value*); }; /* ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". */ typedef int (*sqlite3_loadext_entry)( | > > | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | void (*xInv)(sqlite3_context*,int,sqlite3_value**), void(*xDestroy)(void*)); /* Version 3.26.0 and later */ const char *(*normalized_sql)(sqlite3_stmt*); /* Version 3.28.0 and later */ int (*stmt_isexplain)(sqlite3_stmt*); int (*value_frombind)(sqlite3_value*); /* Version 3.30.0 and later */ int (*drop_modules)(sqlite3*,const char**); }; /* ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". */ typedef int (*sqlite3_loadext_entry)( |
︙ | ︙ | |||
610 611 612 613 614 615 616 617 618 619 620 621 622 623 | /* Version 3.25.0 and later */ #define sqlite3_create_window_function sqlite3_api->create_window_function /* Version 3.26.0 and later */ #define sqlite3_normalized_sql sqlite3_api->normalized_sql /* Version 3.28.0 and later */ #define sqlite3_stmt_isexplain sqlite3_api->isexplain #define sqlite3_value_frombind sqlite3_api->frombind #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; | > > | 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 | /* Version 3.25.0 and later */ #define sqlite3_create_window_function sqlite3_api->create_window_function /* Version 3.26.0 and later */ #define sqlite3_normalized_sql sqlite3_api->normalized_sql /* Version 3.28.0 and later */ #define sqlite3_stmt_isexplain sqlite3_api->isexplain #define sqlite3_value_frombind sqlite3_api->frombind /* Version 3.30.0 and later */ #define sqlite3_drop_modules sqlite3_api->drop_modules #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
208 209 210 211 212 213 214 | ** that vary from one machine to the next. ** ** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on ** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)). ** So we have to define the macros in different ways depending on the ** compiler. */ | > > > | < < < | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | ** that vary from one machine to the next. ** ** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on ** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)). ** So we have to define the macros in different ways depending on the ** compiler. */ #if defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */ # define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X)) #elif defined(__PTRDIFF_TYPE__) /* This case should work for GCC */ # define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X)) #elif !defined(__GNUC__) /* Works for compilers other than LLVM */ # define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X]) # define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0)) #else /* Generates a warning - but it always works */ # define SQLITE_INT_TO_PTR(X) ((void*)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(X)) #endif /* ** A macro to hint to the compiler that a function should not be |
︙ | ︙ | |||
931 932 933 934 935 936 937 | # define SQLITE_DEFAULT_MMAP_SIZE 0 #endif #if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE # undef SQLITE_DEFAULT_MMAP_SIZE # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE #endif | < < < < < < < < < < < < < < | 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | # define SQLITE_DEFAULT_MMAP_SIZE 0 #endif #if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE # undef SQLITE_DEFAULT_MMAP_SIZE # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE #endif /* ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not ** the Select query generator tracing logic is turned on. */ #if defined(SQLITE_ENABLE_SELECTTRACE) # define SELECTTRACE_ENABLED 1 #else |
︙ | ︙ | |||
1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 | struct sqlite3InitInfo { /* Information used during initialization */ int newTnum; /* Rootpage of table being initialized */ u8 iDb; /* Which db file is being initialized */ u8 busy; /* TRUE if currently initializing */ unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */ unsigned imposterTable : 1; /* Building an imposter table */ unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */ } init; int nVdbeActive; /* Number of VDBEs currently running */ int nVdbeRead; /* Number of active VDBEs that read or write */ int nVdbeWrite; /* Number of active VDBEs that read and write */ int nVdbeExec; /* Number of nested calls to VdbeExec() */ int nVDestroy; /* Number of active OP_VDestroy operations */ int nExtension; /* Number of loaded extensions */ | > | 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 | struct sqlite3InitInfo { /* Information used during initialization */ int newTnum; /* Rootpage of table being initialized */ u8 iDb; /* Which db file is being initialized */ u8 busy; /* TRUE if currently initializing */ unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */ unsigned imposterTable : 1; /* Building an imposter table */ unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */ char **azInit; /* "type", "name", and "tbl_name" columns */ } init; int nVdbeActive; /* Number of VDBEs currently running */ int nVdbeRead; /* Number of active VDBEs that read or write */ int nVdbeWrite; /* Number of active VDBEs that read and write */ int nVdbeExec; /* Number of nested calls to VdbeExec() */ int nVDestroy; /* Number of active OP_VDestroy operations */ int nExtension; /* Number of loaded extensions */ |
︙ | ︙ | |||
1557 1558 1559 1560 1561 1562 1563 | #define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */ #define SQLITE_ResetDatabase 0x02000000 /* Reset the database */ #define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */ #define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/ #define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */ #define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/ #define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/ | > | | | | | | | | 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 | #define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */ #define SQLITE_ResetDatabase 0x02000000 /* Reset the database */ #define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */ #define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/ #define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */ #define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/ #define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/ #define SQLITE_EnableView 0x80000000 /* Enable the use of views */ #define SQLITE_NoopUpdate HI(0x0001000) /* UPDATE operations are no-ops */ /* Flags used only if debugging */ #define HI(X) ((u64)(X)<<32) #ifdef SQLITE_DEBUG #define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */ #define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */ #define SQLITE_VdbeTrace HI(0x0400000) /* True to trace VDBE execution */ #define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */ #define SQLITE_VdbeEQP HI(0x1000000) /* Debug EXPLAIN QUERY PLAN */ #define SQLITE_ParserTrace HI(0x2000000) /* PRAGMA parser_trace=ON */ #endif /* ** Allowed values for sqlite3.mDbFlags */ #define DBFLAG_SchemaChange 0x0001 /* Uncommitted Hash table changes */ #define DBFLAG_PreferBuiltin 0x0002 /* Preference to built-in funcs */ |
︙ | ︙ | |||
1595 1596 1597 1598 1599 1600 1601 | #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 */ | | | | 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 | #define SQLITE_DistinctOpt 0x0010 /* DISTINCT using indexes */ #define SQLITE_CoverIdxScan 0x0020 /* Covering index scans */ #define SQLITE_OrderByIdxJoin 0x0040 /* ORDER BY of joins via index */ #define SQLITE_Transitive 0x0080 /* Transitive constraints */ #define SQLITE_OmitNoopJoin 0x0100 /* Omit unused tables in joins */ #define SQLITE_CountOfView 0x0200 /* The count-of-view optimization */ #define SQLITE_CursorHints 0x0400 /* Add OP_CursorHint opcodes */ #define SQLITE_Stat4 0x0800 /* Use STAT4 data */ /* TH3 expects the Stat4 ^^^^^^ value to be 0x0800. Don't change it */ #define SQLITE_PushDown 0x1000 /* The push-down optimization */ #define SQLITE_SimplifyJoin 0x2000 /* Convert LEFT JOIN to JOIN */ #define SQLITE_SkipScan 0x4000 /* Skip-scans */ #define SQLITE_PropagateConst 0x8000 /* The constant propagation opt */ #define SQLITE_AllOpts 0xffff /* All optimizations */ /* |
︙ | ︙ | |||
1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 | ** are assert() statements in the code to verify this. ** ** Value constraints (enforced via assert()): ** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg ** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ #define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */ #define SQLITE_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */ #define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */ #define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/ #define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */ #define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */ #define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */ #define SQLITE_FUNC_COALESCE 0x0200 /* Built-in coalesce() or ifnull() */ #define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */ #define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */ #define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */ #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a ** single query - might change over time */ #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */ #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */ #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are ** used to create the initializers for the FuncDef structures. ** ** FUNCTION(zName, nArg, iArg, bNC, xFunc) ** Used to create a scalar function definition of a function zName | > > > | 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 | ** are assert() statements in the code to verify this. ** ** Value constraints (enforced via assert()): ** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg ** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API ** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ #define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */ #define SQLITE_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */ #define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */ #define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/ #define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */ #define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */ #define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */ #define SQLITE_FUNC_COALESCE 0x0200 /* Built-in coalesce() or ifnull() */ #define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */ #define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */ #define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */ #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a ** single query - might change over time */ #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */ #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */ #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are ** used to create the initializers for the FuncDef structures. ** ** FUNCTION(zName, nArg, iArg, bNC, xFunc) ** Used to create a scalar function definition of a function zName |
︙ | ︙ | |||
1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 | ** Each SQLite module (virtual table definition) is defined by an ** instance of the following structure, stored in the sqlite3.aModule ** hash table. */ struct Module { const sqlite3_module *pModule; /* Callback pointers */ const char *zName; /* Name passed to create_module() */ void *pAux; /* pAux passed to create_module() */ void (*xDestroy)(void *); /* Module destructor function */ Table *pEpoTab; /* Eponymous table for this module */ }; /* ** information about each column of an SQL table is held in an instance | > | 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 | ** Each SQLite module (virtual table definition) is defined by an ** instance of the following structure, stored in the sqlite3.aModule ** hash table. */ struct Module { const sqlite3_module *pModule; /* Callback pointers */ const char *zName; /* Name passed to create_module() */ int nRefModule; /* Number of pointers to this object */ void *pAux; /* pAux passed to create_module() */ void (*xDestroy)(void *); /* Module destructor function */ Table *pEpoTab; /* Eponymous table for this module */ }; /* ** information about each column of an SQL table is held in an instance |
︙ | ︙ | |||
1882 1883 1884 1885 1886 1887 1888 | ** But rather than start with 0 or 1, we begin with 'A'. That way, ** when multiple affinity types are concatenated into a string and ** used as the P4 operand, they will be more readable. ** ** Note also that the numeric types are grouped together so that testing ** for a numeric type is a single comparison. And the BLOB type is first. */ | > | | | | | | 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 | ** But rather than start with 0 or 1, we begin with 'A'. That way, ** when multiple affinity types are concatenated into a string and ** used as the P4 operand, they will be more readable. ** ** Note also that the numeric types are grouped together so that testing ** for a numeric type is a single comparison. And the BLOB type is first. */ #define SQLITE_AFF_NONE 0x40 /* '@' */ #define SQLITE_AFF_BLOB 0x41 /* 'A' */ #define SQLITE_AFF_TEXT 0x42 /* 'B' */ #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ #define SQLITE_AFF_REAL 0x45 /* 'E' */ #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) /* ** The SQLITE_AFF_MASK values masks off the significant bits of an ** affinity value. */ |
︙ | ︙ | |||
2154 2155 2156 2157 2158 2159 2160 | */ struct KeyInfo { u32 nRef; /* Number of references to this KeyInfo object */ u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ u16 nKeyField; /* Number of key columns in the index */ u16 nAllField; /* Total columns, including key plus others */ sqlite3 *db; /* The database connection */ | | > > > | 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 | */ struct KeyInfo { u32 nRef; /* Number of references to this KeyInfo object */ u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ u16 nKeyField; /* Number of key columns in the index */ u16 nAllField; /* Total columns, including key plus others */ sqlite3 *db; /* The database connection */ u8 *aSortFlags; /* Sort order for each column. */ CollSeq *aColl[1]; /* Collating sequence for each term of the key */ }; #define KEYINFO_ORDER_DESC 0x01 #define KEYINFO_ORDER_BIGNULL 0x02 /* ** This object holds a record which has been parsed out into individual ** fields, for the purposes of doing a comparison. ** ** A record is an object that contains one or more fields of data. ** Records are used to store the content of a table row and to store |
︙ | ︙ | |||
2265 2266 2267 2268 2269 2270 2271 | unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ unsigned isResized:1; /* True if resizeIndexObject() has been called */ unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ | | | 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 | unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ unsigned isResized:1; /* True if resizeIndexObject() has been called */ unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ #ifdef SQLITE_ENABLE_STAT4 int nSample; /* Number of elements in aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ IndexSample *aSample; /* Samples of the left-most key */ tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ #endif |
︙ | ︙ | |||
2297 2298 2299 2300 2301 2302 2303 | /* The Index.aiColumn[] values are normally positive integer. But ** there are some negative values that have special meaning: */ #define XN_ROWID (-1) /* Indexed column is the rowid */ #define XN_EXPR (-2) /* Indexed column is an expression */ /* | | | 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 | /* The Index.aiColumn[] values are normally positive integer. But ** there are some negative values that have special meaning: */ #define XN_ROWID (-1) /* Indexed column is the rowid */ #define XN_EXPR (-2) /* Indexed column is an expression */ /* ** Each sample stored in the sqlite_stat4 table is represented in memory ** using a structure of this type. See documentation at the top of the ** analyze.c source file for additional information. */ struct IndexSample { void *p; /* Pointer to sampled record */ int n; /* Size of record in bytes */ tRowcnt *anEq; /* Est. number of rows where the key equals this sample */ |
︙ | ︙ | |||
2455 2456 2457 2458 2459 2460 2461 | ** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees ** are contained within the same memory allocation. Note, however, that ** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately ** allocated, regardless of whether or not EP_Reduced is set. */ struct Expr { u8 op; /* Operation performed by this node */ | | | 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 | ** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees ** are contained within the same memory allocation. Note, however, that ** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately ** allocated, regardless of whether or not EP_Reduced is set. */ struct Expr { u8 op; /* Operation performed by this node */ char affExpr; /* affinity, or RAISE type */ u32 flags; /* Various flags. EP_* See below */ union { char *zToken; /* Token value. Zero terminated and dequoted */ int iValue; /* Non-negative integer value if EP_IntValue */ } u; /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no |
︙ | ︙ | |||
2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 | #if SQLITE_MAX_EXPR_DEPTH>0 int nHeight; /* Height of the tree headed by this node */ #endif int iTable; /* TK_COLUMN: cursor number of table holding column ** TK_REGISTER: register number ** TK_TRIGGER: 1 -> new, 0 -> old ** EP_Unlikely: 134217728 times likelihood ** TK_SELECT: 1st register of result vector */ ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. ** TK_VARIABLE: variable number (always >= 1). ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op ** TK_COLUMN: the value of p5 for OP_Column ** TK_AGG_FUNCTION: nesting depth */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ union { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL ** for a column of an index on an expression */ | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 | #if SQLITE_MAX_EXPR_DEPTH>0 int nHeight; /* Height of the tree headed by this node */ #endif int iTable; /* TK_COLUMN: cursor number of table holding column ** TK_REGISTER: register number ** TK_TRIGGER: 1 -> new, 0 -> old ** EP_Unlikely: 134217728 times likelihood ** TK_SELECT_COLUMN: Number of columns on the LHS ** TK_SELECT: 1st register of result vector */ ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. ** TK_VARIABLE: variable number (always >= 1). ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op ** TK_COLUMN: the value of p5 for OP_Column ** TK_AGG_FUNCTION: nesting depth */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ union { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL ** for a column of an index on an expression */ Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */ struct { /* TK_IN, TK_SELECT, and TK_EXISTS */ int iAddr; /* Subroutine entry address */ int regReturn; /* Register used to hold return address */ } sub; } y; }; /* ** The following are the meanings of bits in the Expr.flags field. ** Value restrictions: ** ** EP_Agg == NC_HasAgg == SF_HasAgg ** EP_Win == NC_HasWin */ #define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ #define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */ #define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */ #define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */ #define EP_Agg 0x000010 /* Contains one or more aggregate functions */ #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ #define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ /* 0x000200 Available for reuse */ #define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ #define EP_Skip 0x001000 /* Operator does not contribute to affinity */ #define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ #define EP_Win 0x008000 /* Contains window functions */ #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ #define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ #define EP_Alias 0x400000 /* Is an alias for a result set column */ #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ #define EP_Quoted 0x4000000 /* TK_ID was originally quoted */ #define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */ #define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ #define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ #define EP_Indirect 0x40000000 /* Contained within a TRIGGER or a VIEW */ /* ** The EP_Propagate mask is a set of properties that automatically propagate ** upwards into parent nodes. */ #define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc) |
︙ | ︙ | |||
2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 | #define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */ /* ** Flags passed to the sqlite3ExprDup() function. See the header comment ** above sqlite3ExprDup() for details. */ #define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */ /* ** A list of expressions. Each expression may optionally have a ** name. An expr/name combination can be used in several ways, such ** as the list of "expr AS ID" fields following a "SELECT" or in the ** list of "ID = expr" items in an UPDATE. A list of expressions can ** also be used as the argument to a function, in which case the a.zName | > > > > > > > > | 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 | #define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */ /* ** Flags passed to the sqlite3ExprDup() function. See the header comment ** above sqlite3ExprDup() for details. */ #define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */ /* ** True if the expression passed as an argument was a function with ** an OVER() clause (a window function). */ #define IsWindowFunc(p) ( \ ExprHasProperty((p), EP_WinFunc) && p->y.pWin->eFrmType!=TK_FILTER \ ) /* ** A list of expressions. Each expression may optionally have a ** name. An expr/name combination can be used in several ways, such ** as the list of "expr AS ID" fields following a "SELECT" or in the ** list of "ID = expr" items in an UPDATE. A list of expressions can ** also be used as the argument to a function, in which case the a.zName |
︙ | ︙ | |||
2609 2610 2611 2612 2613 2614 2615 | */ struct ExprList { int nExpr; /* Number of expressions on the list */ struct ExprList_item { /* For each expression in the list */ Expr *pExpr; /* The parse tree for this expression */ char *zName; /* Token associated with this expression */ char *zSpan; /* Original text of the expression */ | | > | 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 | */ struct ExprList { int nExpr; /* Number of expressions on the list */ struct ExprList_item { /* For each expression in the list */ Expr *pExpr; /* The parse tree for this expression */ char *zName; /* Token associated with this expression */ char *zSpan; /* Original text of the expression */ u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */ unsigned done :1; /* A flag to indicate when processing is finished */ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ unsigned reusable :1; /* Constant expression is reusable */ unsigned bSorterRef :1; /* Defer evaluation until after sorting */ unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */ union { struct { u16 iOrderByCol; /* For ORDER BY, column number in result set */ u16 iAlias; /* Index into Parse.aAlias[] for zName */ } x; int iConstExprReg; /* Register in which Expr value is cached */ } u; |
︙ | ︙ | |||
2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 | #define SF_MinMaxAgg 0x01000 /* Aggregate containing min() or max() */ #define SF_Recursive 0x02000 /* The recursive part of a recursive CTE */ #define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */ #define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */ #define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */ #define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ #define SF_ComplexResult 0x40000 /* Result contains subquery or function */ /* ** The results of a SELECT can be distributed in several ways, as defined ** by one of the following macros. The "SRT" prefix means "SELECT Result ** Type". ** ** SRT_Union Store results as a key in a temporary index | > | 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 | #define SF_MinMaxAgg 0x01000 /* Aggregate containing min() or max() */ #define SF_Recursive 0x02000 /* The recursive part of a recursive CTE */ #define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */ #define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */ #define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */ #define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ #define SF_ComplexResult 0x40000 /* Result contains subquery or function */ #define SF_WhereBegin 0x80000 /* Really a WhereBegin() call. Debug Only */ /* ** The results of a SELECT can be distributed in several ways, as defined ** by one of the following macros. The "SRT" prefix means "SELECT Result ** Type". ** ** SRT_Union Store results as a key in a temporary index |
︙ | ︙ | |||
3408 3409 3410 3411 3412 3413 3414 | /* ** Structure containing global configuration data for the SQLite library. ** ** This structure also contains some state information. */ struct Sqlite3Config { int bMemstat; /* True to enable memory status */ | | | | | | > | 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 | /* ** Structure containing global configuration data for the SQLite library. ** ** This structure also contains some state information. */ struct Sqlite3Config { int bMemstat; /* True to enable memory status */ u8 bCoreMutex; /* True to enable core mutexing */ u8 bFullMutex; /* True to enable full mutexing */ u8 bOpenUri; /* True to interpret filenames as URIs */ u8 bUseCis; /* Use covering indices for full-scans */ u8 bSmallMalloc; /* Avoid large memory allocations if true */ u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ int mxStrlen; /* Maximum string length */ int neverCorrupt; /* Database is always well-formed */ int szLookaside; /* Default lookaside buffer size */ int nLookaside; /* Default lookaside buffer count */ int nStmtSpill; /* Stmt-journal spill-to-disk threshold */ sqlite3_mem_methods m; /* Low-level memory allocation interface */ sqlite3_mutex_methods mutex; /* Low-level mutex interface */ |
︙ | ︙ | |||
3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 | #ifndef SQLITE_UNTESTABLE int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ int bInternalFunctions; /* Internal SQL functions are visible */ int iOnceResetThreshold; /* When to reset OP_Once counters */ u32 szSorterRef; /* Min size in bytes to use sorter-refs */ }; /* ** This macro is used inside of assert() statements to indicate that ** the assert is only valid on a well-formed database. Instead of: ** ** assert( X ); | > | 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 | #ifndef SQLITE_UNTESTABLE int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ int bInternalFunctions; /* Internal SQL functions are visible */ int iOnceResetThreshold; /* When to reset OP_Once counters */ u32 szSorterRef; /* Min size in bytes to use sorter-refs */ unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */ }; /* ** This macro is used inside of assert() statements to indicate that ** the assert is only valid on a well-formed database. Instead of: ** ** assert( X ); |
︙ | ︙ | |||
3560 3561 3562 3563 3564 3565 3566 | struct TreeView { int iLevel; /* Which level of the tree we are on */ u8 bLine[100]; /* Draw vertical in column i if bLine[i] is true */ }; #endif /* SQLITE_DEBUG */ /* | | > | > > > > > | | > > > > | | 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 | struct TreeView { int iLevel; /* Which level of the tree we are on */ u8 bLine[100]; /* Draw vertical in column i if bLine[i] is true */ }; #endif /* SQLITE_DEBUG */ /* ** This object is used in various ways, most (but not all) related to window ** functions. ** ** (1) A single instance of this structure is attached to the ** the Expr.y.pWin field for each window function in an expression tree. ** This object holds the information contained in the OVER clause, ** plus additional fields used during code generation. ** ** (2) All window functions in a single SELECT form a linked-list ** attached to Select.pWin. The Window.pFunc and Window.pExpr ** fields point back to the expression that is the window function. ** ** (3) The terms of the WINDOW clause of a SELECT are instances of this ** object on a linked list attached to Select.pWinDefn. ** ** (4) For an aggregate function with a FILTER clause, an instance ** of this object is stored in Expr.y.pWin with eFrmType set to ** TK_FILTER. In this case the only field used is Window.pFilter. ** ** The uses (1) and (2) are really the same Window object that just happens ** to be accessible in two different ways. Use case (3) are separate objects. */ struct Window { char *zName; /* Name of window (may be NULL) */ char *zBase; /* Name of base window for chaining (may be NULL) */ ExprList *pPartition; /* PARTITION BY clause */ ExprList *pOrderBy; /* ORDER BY clause */ u8 eFrmType; /* TK_RANGE, TK_GROUPS, TK_ROWS, or 0 */ u8 eStart; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */ u8 eEnd; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */ u8 bImplicitFrame; /* True if frame was implicitly specified */ u8 eExclude; /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */ Expr *pStart; /* Expression for "<expr> PRECEDING" */ Expr *pEnd; /* Expression for "<expr> FOLLOWING" */ Window **ppThis; /* Pointer to this object in Select.pWin list */ Window *pNextWin; /* Next window function belonging to this SELECT */ Expr *pFilter; /* The FILTER expression */ FuncDef *pFunc; /* The function */ int iEphCsr; /* Partition buffer or Peer buffer */ int regAccum; /* Accumulator */ int regResult; /* Interim result */ int csrApp; /* Function cursor (used by min/max) */ int regApp; /* Function register (also used by min/max) */ int regPart; /* Array of registers for PARTITION BY values */ Expr *pOwner; /* Expression object this window is attached to */ int nBufferCol; /* Number of columns in buffer table */ int iArgCol; /* Offset of first argument for this function */ int regOne; /* Register containing constant value 1 */ int regStartRowid; int regEndRowid; u8 bExprArgs; /* Defer evaluation of window function arguments ** due to the SQLITE_SUBTYPE flag */ }; #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3WindowDelete(sqlite3*, Window*); void sqlite3WindowUnlinkFromSelect(Window*); void sqlite3WindowListDelete(sqlite3 *db, Window *p); Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8); void sqlite3WindowAttach(Parse*, Expr*, Window*); void sqlite3WindowLink(Select *pSel, Window *pWin); int sqlite3WindowCompare(Parse*, Window*, Window*, int); void sqlite3WindowCodeInit(Parse*, 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); |
︙ | ︙ | |||
3883 3884 3885 3886 3887 3888 3889 | Expr *sqlite3ExprSimplifiedAndOr(Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); void sqlite3ExprUnmapAndDelete(Parse*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); | | | | | 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 | Expr *sqlite3ExprSimplifiedAndOr(Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); void sqlite3ExprUnmapAndDelete(Parse*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); void sqlite3ExprListSetSortOrder(ExprList*,int,int); void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); void sqlite3ExprListDelete(sqlite3*, ExprList*); u32 sqlite3ExprListFlags(const ExprList*); int sqlite3IndexHasDuplicateRootPage(Index*); int sqlite3Init(sqlite3*, char**); int sqlite3InitCallback(void*, int, char**, char**); int sqlite3InitOne(sqlite3*, int, char**, u32); void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); #ifndef SQLITE_OMIT_VIRTUALTABLE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName); #endif void sqlite3ResetAllSchemasOfConnection(sqlite3*); void sqlite3ResetOneSchema(sqlite3*,int); void sqlite3CollapseDatabaseArray(sqlite3*); void sqlite3CommitInternalChanges(sqlite3*); void sqlite3DeleteColumnNames(sqlite3*,Table*); int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char); Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); void sqlite3OpenMasterTable(Parse *, int); Index *sqlite3PrimaryKeyIndex(Table*); i16 sqlite3ColumnOfIndex(Index*, i16); void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); #if SQLITE_ENABLE_HIDDEN_COLUMNS void sqlite3ColumnPropertiesFromName(Table*, Column*); #else |
︙ | ︙ | |||
4206 4207 4208 4209 4210 4211 4212 | u32 sqlite3Utf8Read(const u8**); LogEst sqlite3LogEst(u64); LogEst sqlite3LogEstAdd(LogEst,LogEst); #ifndef SQLITE_OMIT_VIRTUALTABLE LogEst sqlite3LogEstFromDouble(double); #endif #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ | | | 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 | u32 sqlite3Utf8Read(const u8**); LogEst sqlite3LogEst(u64); LogEst sqlite3LogEstAdd(LogEst,LogEst); #ifndef SQLITE_OMIT_VIRTUALTABLE LogEst sqlite3LogEstFromDouble(double); #endif #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ defined(SQLITE_ENABLE_STAT4) || \ defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) u64 sqlite3LogEstToInt(LogEst); #endif VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int); const char *sqlite3VListNumToName(VList*,int); int sqlite3VListNameToNum(VList*,const char*,int); |
︙ | ︙ | |||
4272 4273 4274 4275 4276 4277 4278 4279 4280 | 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*); int sqlite3CheckCollSeq(Parse *, CollSeq *); int sqlite3WritableSchema(sqlite3*); | > | | 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 | 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*); Expr *sqlite3ExprSkipCollateAndLikely(Expr*); int sqlite3CheckCollSeq(Parse *, CollSeq *); int sqlite3WritableSchema(sqlite3*); int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*); void sqlite3VdbeSetChanges(sqlite3 *, int); int sqlite3AddInt64(i64*,i64); int sqlite3SubInt64(i64*,i64); int sqlite3MulInt64(i64*,i64); int sqlite3AbsInt32(int); #ifdef SQLITE_ENABLE_8_3_NAMES void sqlite3FileSuffix3(const char*, char*); |
︙ | ︙ | |||
4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 | Schema *sqlite3SchemaGet(sqlite3 *, Btree *); int sqlite3SchemaToIndex(sqlite3 *db, Schema *); KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); void sqlite3KeyInfoUnref(KeyInfo*); KeyInfo *sqlite3KeyInfoRef(KeyInfo*); KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); #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 **), | > | 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 | Schema *sqlite3SchemaGet(sqlite3 *, Btree *); int sqlite3SchemaToIndex(sqlite3 *db, Schema *); KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); void sqlite3KeyInfoUnref(KeyInfo*); KeyInfo *sqlite3KeyInfoRef(KeyInfo*); KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); int sqlite3HasExplicitNulls(Parse*, ExprList*); #ifdef SQLITE_DEBUG int sqlite3KeyInfoIsWriteable(KeyInfo*); #endif int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*,int,sqlite3_value **), |
︙ | ︙ | |||
4393 4394 4395 4396 4397 4398 4399 | #ifndef SQLITE_OMIT_SUBQUERY int sqlite3ExprCheckIN(Parse*, Expr*); #else # define sqlite3ExprCheckIN(x,y) SQLITE_OK #endif | | < | 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 | #ifndef SQLITE_OMIT_SUBQUERY int sqlite3ExprCheckIN(Parse*, Expr*); #else # define sqlite3ExprCheckIN(x,y) SQLITE_OK #endif #ifdef SQLITE_ENABLE_STAT4 int sqlite3Stat4ProbeSetValue( Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*); int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); void sqlite3Stat4ProbeFree(UnpackedRecord*); int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**); char sqlite3IndexColumnAffinity(sqlite3*, Index*, int); #endif |
︙ | ︙ | |||
4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 | # define sqlite3VtabClear(Y) # define sqlite3VtabSync(X,Y) SQLITE_OK # define sqlite3VtabRollback(X) # define sqlite3VtabCommit(X) # define sqlite3VtabInSync(db) 0 # define sqlite3VtabLock(X) # define sqlite3VtabUnlock(X) # define sqlite3VtabUnlockList(X) # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK # define sqlite3GetVTable(X,Y) ((VTable*)0) #else void sqlite3VtabClear(sqlite3 *db, Table*); void sqlite3VtabDisconnect(sqlite3 *db, Table *p); int sqlite3VtabSync(sqlite3 *db, Vdbe*); int sqlite3VtabRollback(sqlite3 *db); int sqlite3VtabCommit(sqlite3 *db); void sqlite3VtabLock(VTable *); void sqlite3VtabUnlock(VTable *); void sqlite3VtabUnlockList(sqlite3*); int sqlite3VtabSavepoint(sqlite3 *, int, int); void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); VTable *sqlite3GetVTable(sqlite3*, Table*); Module *sqlite3VtabCreateModule( sqlite3*, const char*, | > > | 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 | # define sqlite3VtabClear(Y) # define sqlite3VtabSync(X,Y) SQLITE_OK # define sqlite3VtabRollback(X) # define sqlite3VtabCommit(X) # define sqlite3VtabInSync(db) 0 # define sqlite3VtabLock(X) # define sqlite3VtabUnlock(X) # define sqlite3VtabModuleUnref(D,X) # define sqlite3VtabUnlockList(X) # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK # define sqlite3GetVTable(X,Y) ((VTable*)0) #else void sqlite3VtabClear(sqlite3 *db, Table*); void sqlite3VtabDisconnect(sqlite3 *db, Table *p); int sqlite3VtabSync(sqlite3 *db, Vdbe*); int sqlite3VtabRollback(sqlite3 *db); int sqlite3VtabCommit(sqlite3 *db); void sqlite3VtabLock(VTable *); void sqlite3VtabUnlock(VTable *); void sqlite3VtabModuleUnref(sqlite3*,Module*); void sqlite3VtabUnlockList(sqlite3*); int sqlite3VtabSavepoint(sqlite3 *, int, int); void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); VTable *sqlite3GetVTable(sqlite3*, Table*); Module *sqlite3VtabCreateModule( sqlite3*, const char*, |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
1913 1914 1915 1916 1917 1918 1919 | SqliteDb *pDb = (SqliteDb*)cd; int choice; int rc = TCL_OK; static const char *DB_strs[] = { "authorizer", "backup", "bind_fallback", "busy", "cache", "changes", "close", "collate", "collation_needed", | | | | | | | | | | | | | | | | | | | | | | | | 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 | SqliteDb *pDb = (SqliteDb*)cd; int choice; int rc = TCL_OK; static const char *DB_strs[] = { "authorizer", "backup", "bind_fallback", "busy", "cache", "changes", "close", "collate", "collation_needed", "commit_hook", "complete", "config", "copy", "deserialize", "enable_load_extension", "errorcode", "eval", "exists", "function", "incrblob", "interrupt", "last_insert_rowid", "nullvalue", "onecolumn", "preupdate", "profile", "progress", "rekey", "restore", "rollback_hook", "serialize", "status", "timeout", "total_changes", "trace", "trace_v2", "transaction", "unlock_notify", "update_hook", "version", "wal_hook", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK, DB_BUSY, DB_CACHE, DB_CHANGES, DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG, DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_EVAL, DB_EXISTS, DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE, DB_PROGRESS, DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); return TCL_ERROR; } |
︙ | ︙ | |||
2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 | } isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) ); pResult = Tcl_GetObjResult(interp); Tcl_SetBooleanObj(pResult, isComplete); #endif break; } /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR? ** ** Copy data into table from filename, optionally using SEPARATOR ** as column separators. If a column contains a null string, or the ** value of NULLINDICATOR, a NULL is inserted for the column. ** conflict-algorithm is one of the sqlite conflict algorithms: | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 | } isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) ); pResult = Tcl_GetObjResult(interp); Tcl_SetBooleanObj(pResult, isComplete); #endif break; } /* $db config ?OPTION? ?BOOLEAN? ** ** Configure the database connection using the sqlite3_db_config() ** interface. */ case DB_CONFIG: { static const struct DbConfigChoices { const char *zName; int op; } aDbConfig[] = { { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, { "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 }, { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, }; Tcl_Obj *pResult; int ii; if( objc>4 ){ Tcl_WrongNumArgs(interp, 2, objv, "?OPTION? ?BOOLEAN?"); return TCL_ERROR; } if( objc==2 ){ /* With no arguments, list all configuration options and with the ** current value */ pResult = Tcl_NewListObj(0,0); for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){ int v = 0; sqlite3_db_config(pDb->db, aDbConfig[ii].op, -1, &v); Tcl_ListObjAppendElement(interp, pResult, Tcl_NewStringObj(aDbConfig[ii].zName,-1)); Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(v)); } }else{ const char *zOpt = Tcl_GetString(objv[2]); int onoff = -1; int v = 0; if( zOpt[0]=='-' ) zOpt++; for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){ if( strcmp(aDbConfig[ii].zName, zOpt)==0 ) break; } if( ii>=sizeof(aDbConfig)/sizeof(aDbConfig[0]) ){ Tcl_AppendResult(interp, "unknown config option: \"", zOpt, "\"", (void*)0); return TCL_ERROR; } if( objc==4 ){ if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ){ return TCL_ERROR; } } sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v); pResult = Tcl_NewIntObj(v); } Tcl_SetObjResult(interp, pResult); break; } /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR? ** ** Copy data into table from filename, optionally using SEPARATOR ** as column separators. If a column contains a null string, or the ** value of NULLINDICATOR, a NULL is inserted for the column. ** conflict-algorithm is one of the sqlite conflict algorithms: |
︙ | ︙ | |||
2737 2738 2739 2740 2741 2742 2743 | cd2[1] = (void *)pScript; rc = DbEvalNextCmd(cd2, interp, TCL_OK); } break; } /* | | > > > > > > | 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 | cd2[1] = (void *)pScript; rc = DbEvalNextCmd(cd2, interp, TCL_OK); } break; } /* ** $db function NAME [OPTIONS] SCRIPT ** ** Create a new SQL function called NAME. Whenever that function is ** called, invoke SCRIPT to evaluate the function. ** ** Options: ** --argcount N Function has exactly N arguments ** --deterministic The function is pure ** --directonly Prohibit use inside triggers and views ** --returntype TYPE Specify the return type of the function */ case DB_FUNCTION: { int flags = SQLITE_UTF8; SqlFunc *pFunc; Tcl_Obj *pScript; char *zName; int nArg = -1; |
︙ | ︙ | |||
2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 | (char*)0); return TCL_ERROR; } i++; }else if( n>1 && strncmp(z, "-deterministic",n)==0 ){ flags |= SQLITE_DETERMINISTIC; }else if( n>1 && strncmp(z, "-returntype", n)==0 ){ const char *azType[] = {"integer", "real", "text", "blob", "any", 0}; assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 ); assert( SQLITE_BLOB==4 && SQLITE_NULL==5 ); if( i==(objc-2) ){ Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0); return TCL_ERROR; } i++; if( Tcl_GetIndexFromObj(interp, objv[i], azType, "type", 0, &eType) ){ return TCL_ERROR; } eType++; }else{ Tcl_AppendResult(interp, "bad option \"", z, | > > > | > | 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 | (char*)0); return TCL_ERROR; } i++; }else if( n>1 && strncmp(z, "-deterministic",n)==0 ){ flags |= SQLITE_DETERMINISTIC; }else if( n>1 && strncmp(z, "-directonly",n)==0 ){ flags |= SQLITE_DIRECTONLY; }else if( n>1 && strncmp(z, "-returntype", n)==0 ){ const char *azType[] = {"integer", "real", "text", "blob", "any", 0}; assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 ); assert( SQLITE_BLOB==4 && SQLITE_NULL==5 ); if( i==(objc-2) ){ Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0); return TCL_ERROR; } i++; if( Tcl_GetIndexFromObj(interp, objv[i], azType, "type", 0, &eType) ){ return TCL_ERROR; } eType++; }else{ Tcl_AppendResult(interp, "bad option \"", z, "\": must be -argcount, -deterministic, -directonly," " or -returntype", (char*)0 ); return TCL_ERROR; } } pScript = objv[objc-1]; zName = Tcl_GetStringFromObj(objv[2], 0); |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 | } #endif if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0); return TCL_OK; } /* ** Routines to implement the x_count() aggregate function. ** ** x_count() counts the number of non-null arguments. But there are ** some twists for testing purposes. ** | > > > > > > > > > > > > > > > > > > > > > > > > > | 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 | } #endif if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0); return TCL_OK; } /* ** Usage: sqlite3_drop_modules DB ?NAME ...? ** ** Invoke the sqlite3_drop_modules(D,L) interface on database ** connection DB, in order to drop all modules except those named in ** the argument. */ static int SQLITE_TCLAPI test_drop_modules( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ sqlite3 *db; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; sqlite3_drop_modules(db, argc>2 ? (const char**)(argv+2) : 0); return TCL_OK; } /* ** Routines to implement the x_count() aggregate function. ** ** x_count() counts the number of non-null arguments. But there are ** some twists for testing purposes. ** |
︙ | ︙ | |||
6369 6370 6371 6372 6373 6374 6375 | */ static int SQLITE_TCLAPI reset_prng_state( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 | */ static int SQLITE_TCLAPI reset_prng_state( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ sqlite3_randomness(0,0); return TCL_OK; } /* ** tclcmd: prng_seed INT ?DB? ** ** Set up the SQLITE_TESTCTRL_PRNG_SEED pragma with parameter INT and DB. ** INT is an integer. DB is a database connection, or a NULL pointer if ** omitted. ** ** When INT!=0 and DB!=0, set the PRNG seed to the value of the schema ** cookie for DB, or to INT if the schema cookie happens to be zero. ** ** When INT!=0 and DB==0, set the PRNG seed to just INT. ** ** If INT==0 and DB==0 then use the default procedure of calling the ** xRandomness method on the default VFS to get the PRNG seed. */ static int SQLITE_TCLAPI prng_seed( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ int i = 0; sqlite3 *db = 0; if( objc!=2 && objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "SEED ?DB?"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp,objv[0],&i) ) return TCL_ERROR; if( objc==3 && getDbPointer(interp, Tcl_GetString(objv[2]), &db) ){ return TCL_ERROR; } sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, i, db); return TCL_OK; } /* ** tclcmd: database_may_be_corrupt ** ** Indicate that database files might be corrupt. In other words, set the normal |
︙ | ︙ | |||
7135 7136 7137 7138 7139 7140 7141 | { "groupby-order", SQLITE_GroupByOrder }, { "factor-constants", SQLITE_FactorOutConst }, { "distinct-opt", SQLITE_DistinctOpt }, { "cover-idx-scan", SQLITE_CoverIdxScan }, { "order-by-idx-join", SQLITE_OrderByIdxJoin }, { "transitive", SQLITE_Transitive }, { "omit-noop-join", SQLITE_OmitNoopJoin }, | < | > | 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 | { "groupby-order", SQLITE_GroupByOrder }, { "factor-constants", SQLITE_FactorOutConst }, { "distinct-opt", SQLITE_DistinctOpt }, { "cover-idx-scan", SQLITE_CoverIdxScan }, { "order-by-idx-join", SQLITE_OrderByIdxJoin }, { "transitive", SQLITE_Transitive }, { "omit-noop-join", SQLITE_OmitNoopJoin }, { "stat4", SQLITE_Stat4 }, { "skip-scan", SQLITE_SkipScan }, { "push-down", SQLITE_PushDown }, }; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB OPT BOOLEAN"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; |
︙ | ︙ | |||
7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 | for(iNext=i; zIn[iNext] && zIn[iNext]!='\n'; iNext++){} if( zIn[iNext]=='\n' ) iNext++; while( zIn[i]==' ' || zIn[i]=='\t' ){ i++; } if( a==0 ){ int pgsz; rc = sscanf(zIn+i, "| size %d pagesize %d", &n, &pgsz); if( rc!=2 ) continue; if( n<512 ){ Tcl_AppendResult(interp, "bad 'size' field", (void*)0); return TCL_ERROR; } a = malloc( n ); if( a==0 ){ Tcl_AppendResult(interp, "out of memory", (void*)0); | > > > > > | 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 | for(iNext=i; zIn[iNext] && zIn[iNext]!='\n'; iNext++){} if( zIn[iNext]=='\n' ) iNext++; while( zIn[i]==' ' || zIn[i]=='\t' ){ i++; } if( a==0 ){ int pgsz; rc = sscanf(zIn+i, "| size %d pagesize %d", &n, &pgsz); if( rc!=2 ) continue; if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ){ Tcl_AppendResult(interp, "bad 'pagesize' field", (void*)0); return TCL_ERROR; } n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */ if( n<512 ){ Tcl_AppendResult(interp, "bad 'size' field", (void*)0); return TCL_ERROR; } a = malloc( n ); if( a==0 ){ Tcl_AppendResult(interp, "out of memory", (void*)0); |
︙ | ︙ | |||
7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 | #ifndef SQLITE_OMIT_GET_TABLE { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, #endif { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, { "sqlite3_close_v2", (Tcl_CmdProc*)sqlite_test_close_v2 }, { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, { "sqlite_bind", (Tcl_CmdProc*)test_bind }, { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, { "sqlite3_key", (Tcl_CmdProc*)test_key }, { "sqlite3_rekey", (Tcl_CmdProc*)test_rekey }, { "sqlite_set_magic", (Tcl_CmdProc*)sqlite_set_magic }, | > | 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 | #ifndef SQLITE_OMIT_GET_TABLE { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, #endif { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, { "sqlite3_close_v2", (Tcl_CmdProc*)sqlite_test_close_v2 }, { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, { "sqlite3_drop_modules", (Tcl_CmdProc*)test_drop_modules }, { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, { "sqlite_bind", (Tcl_CmdProc*)test_bind }, { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, { "sqlite3_key", (Tcl_CmdProc*)test_key }, { "sqlite3_rekey", (Tcl_CmdProc*)test_rekey }, { "sqlite_set_magic", (Tcl_CmdProc*)sqlite_set_magic }, |
︙ | ︙ | |||
7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 | { "sqlite3_extended_result_codes", test_extended_result_codes, 0}, { "sqlite3_limit", test_limit, 0}, { "dbconfig_maindbname_icecube", test_dbconfig_maindbname_icecube }, { "save_prng_state", save_prng_state, 0 }, { "restore_prng_state", restore_prng_state, 0 }, { "reset_prng_state", reset_prng_state, 0 }, { "database_never_corrupt", database_never_corrupt, 0}, { "database_may_be_corrupt", database_may_be_corrupt, 0}, { "optimization_control", optimization_control,0}, #if SQLITE_OS_WIN { "lock_win32_file", win32_file_lock, 0 }, { "exists_win32_path", win32_exists_path, 0 }, { "find_win32_file", win32_find_file, 0 }, | > | 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 | { "sqlite3_extended_result_codes", test_extended_result_codes, 0}, { "sqlite3_limit", test_limit, 0}, { "dbconfig_maindbname_icecube", test_dbconfig_maindbname_icecube }, { "save_prng_state", save_prng_state, 0 }, { "restore_prng_state", restore_prng_state, 0 }, { "reset_prng_state", reset_prng_state, 0 }, { "prng_seed", prng_seed, 0 }, { "database_never_corrupt", database_never_corrupt, 0}, { "database_may_be_corrupt", database_may_be_corrupt, 0}, { "optimization_control", optimization_control,0}, #if SQLITE_OS_WIN { "lock_win32_file", win32_file_lock, 0 }, { "exists_win32_path", win32_exists_path, 0 }, { "find_win32_file", win32_find_file, 0 }, |
︙ | ︙ |
Changes to src/test_config.c.
︙ | ︙ | |||
581 582 583 584 585 586 587 | #endif #ifdef SQLITE_ENABLE_STAT4 Tcl_SetVar2(interp, "sqlite_options", "stat4", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "stat4", "0", TCL_GLOBAL_ONLY); #endif | < < < < < < | 581 582 583 584 585 586 587 588 589 590 591 592 593 594 | #endif #ifdef SQLITE_ENABLE_STAT4 Tcl_SetVar2(interp, "sqlite_options", "stat4", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "stat4", "0", TCL_GLOBAL_ONLY); #endif #if defined(SQLITE_ENABLE_STMTVTAB) && !defined(SQLITE_OMIT_VIRTUALTABLE) Tcl_SetVar2(interp, "sqlite_options", "stmtvtab", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "stmtvtab", "0", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
︙ | ︙ |
Changes to src/treeview.c.
︙ | ︙ | |||
172 173 174 175 176 177 178 | pView = sqlite3TreeViewPush(pView, moreToFollow); if( p->pWith ){ sqlite3TreeViewWith(pView, p->pWith, 1); cnt = 1; sqlite3TreeViewPush(pView, 1); } do{ | > > > | | | | | | | > > | > > | 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 | pView = sqlite3TreeViewPush(pView, moreToFollow); if( p->pWith ){ sqlite3TreeViewWith(pView, p->pWith, 1); cnt = 1; sqlite3TreeViewPush(pView, 1); } do{ if( p->selFlags & SF_WhereBegin ){ sqlite3TreeViewLine(pView, "sqlite3WhereBegin()"); }else{ sqlite3TreeViewLine(pView, "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d", ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p->selId, p, p->selFlags, (int)p->nSelectRow ); } if( cnt++ ) sqlite3TreeViewPop(pView); if( p->pPrior ){ n = 1000; }else{ n = 0; if( p->pSrc && p->pSrc->nSrc ) n++; if( p->pWhere ) n++; if( p->pGroupBy ) n++; if( p->pHaving ) n++; if( p->pOrderBy ) n++; if( p->pLimit ) n++; #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWin ) n++; if( p->pWinDefn ) n++; #endif } if( p->pEList ){ sqlite3TreeViewExprList(pView, p->pEList, n>0, "result-set"); } n--; #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWin ){ Window *pX; pView = sqlite3TreeViewPush(pView, (n--)>0); sqlite3TreeViewLine(pView, "window-functions"); for(pX=p->pWin; pX; pX=pX->pNextWin){ sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); |
︙ | ︙ | |||
391 392 393 394 395 396 397 | char zFlgs[60]; pView = sqlite3TreeViewPush(pView, moreToFollow); if( pExpr==0 ){ sqlite3TreeViewLine(pView, "nil"); sqlite3TreeViewPop(pView); return; } | | | > | | > | 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 | char zFlgs[60]; pView = sqlite3TreeViewPush(pView, moreToFollow); if( pExpr==0 ){ sqlite3TreeViewLine(pView, "nil"); sqlite3TreeViewPop(pView); return; } if( pExpr->flags || pExpr->affExpr ){ if( ExprHasProperty(pExpr, EP_FromJoin) ){ sqlite3_snprintf(sizeof(zFlgs),zFlgs," fg.af=%x.%c iRJT=%d", pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n', pExpr->iRightJoinTable); }else{ sqlite3_snprintf(sizeof(zFlgs),zFlgs," fg.af=%x.%c", pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); } }else{ zFlgs[0] = 0; } switch( pExpr->op ){ case TK_AGG_COLUMN: { sqlite3TreeViewLine(pView, "AGG{%d:%d}%s", |
︙ | ︙ | |||
523 524 525 526 527 528 529 | case TK_SPAN: { sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } case TK_COLLATE: { | > > > > | > > | | | | 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 | case TK_SPAN: { sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } case TK_COLLATE: { /* COLLATE operators without the EP_Collate flag are intended to ** emulate collation associated with a table column. Explicit ** COLLATE operators that appear in the original SQL always have ** the EP_Collate bit set */ sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s", !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "", pExpr->u.zToken, zFlgs); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } case TK_AGG_FUNCTION: case TK_FUNCTION: { ExprList *pFarg; /* List of function arguments */ Window *pWin; if( ExprHasProperty(pExpr, EP_TokenOnly) ){ pFarg = 0; pWin = 0; }else{ pFarg = pExpr->x.pList; #ifndef SQLITE_OMIT_WINDOWFUNC pWin = pExpr->y.pWin; #else pWin = 0; #endif } if( pExpr->op==TK_AGG_FUNCTION ){ sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s", pExpr->op2, pExpr->u.zToken, zFlgs); }else{ sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); } if( pFarg ){ sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ sqlite3TreeViewWindow(pView, pWin, 0); |
︙ | ︙ | |||
624 625 626 627 628 629 630 | sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); break; } #ifndef SQLITE_OMIT_TRIGGER case TK_RAISE: { const char *zType = "unk"; | | | 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 | sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); break; } #ifndef SQLITE_OMIT_TRIGGER case TK_RAISE: { const char *zType = "unk"; switch( pExpr->affExpr ){ case OE_Rollback: zType = "rollback"; break; case OE_Abort: zType = "abort"; break; case OE_Fail: zType = "fail"; break; case OE_Ignore: zType = "ignore"; break; } sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); break; |
︙ | ︙ | |||
665 666 667 668 669 670 671 | } if( zBinOp ){ sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs); sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); sqlite3TreeViewExpr(pView, pExpr->pRight, 0); }else if( zUniOp ){ sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs); | | | 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 | } if( zBinOp ){ sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs); sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); sqlite3TreeViewExpr(pView, pExpr->pRight, 0); }else if( zUniOp ){ sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); } sqlite3TreeViewPop(pView); } /* ** Generate a human-readable explanation of an expression list. |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
173 174 175 176 177 178 179 | sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); goto trigger_cleanup; } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ zName = sqlite3NameFromToken(db, pName); | > > > > | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); goto trigger_cleanup; } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ zName = sqlite3NameFromToken(db, pName); if( zName==0 ){ assert( db->mallocFailed ); goto trigger_cleanup; } if( sqlite3CheckObjectName(pParse, zName, "trigger", pTab->zName) ){ goto trigger_cleanup; } assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !IN_RENAME_OBJECT ){ if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); |
︙ | ︙ | |||
336 337 338 339 340 341 342 343 344 345 346 347 348 349 | sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); } if( db->init.busy ){ Trigger *pLink = pTrig; Hash *pHash = &db->aDb[iDb].pSchema->trigHash; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pTrig = sqlite3HashInsert(pHash, zName, pTrig); if( pTrig ){ sqlite3OomFault(db); }else if( pLink->pSchema==pLink->pTabSchema ){ Table *pTab; pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); assert( pTab!=0 ); | > | 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); } if( db->init.busy ){ Trigger *pLink = pTrig; Hash *pHash = &db->aDb[iDb].pSchema->trigHash; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); assert( pLink!=0 ); pTrig = sqlite3HashInsert(pHash, zName, pTrig); if( pTrig ){ sqlite3OomFault(db); }else if( pLink->pSchema==pLink->pTabSchema ){ Table *pTab; pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); assert( pTab!=0 ); |
︙ | ︙ | |||
454 455 456 457 458 459 460 461 462 463 464 465 466 467 | 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); | > > > | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 | pSelect = 0; }else{ pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); } pTriggerStep->pIdList = pColumn; pTriggerStep->pUpsert = pUpsert; pTriggerStep->orconf = orconf; if( pUpsert ){ sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget); } }else{ testcase( pColumn ); sqlite3IdListDelete(db, pColumn); testcase( pUpsert ); sqlite3UpsertDelete(db, pUpsert); } sqlite3SelectDelete(db, pSelect); |
︙ | ︙ | |||
609 610 611 612 613 614 615 | Vdbe *v; sqlite3 *db = pParse->db; int iDb; iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema); assert( iDb>=0 && iDb<db->nDb ); pTable = tableOfTrigger(pTrigger); | < | < > < | 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 | Vdbe *v; sqlite3 *db = pParse->db; int iDb; iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema); assert( iDb>=0 && iDb<db->nDb ); pTable = tableOfTrigger(pTrigger); assert( (pTable && pTable->pSchema==pTrigger->pSchema) || iDb==1 ); #ifndef SQLITE_OMIT_AUTHORIZATION if( pTable ){ int code = SQLITE_DROP_TRIGGER; const char *zDb = db->aDb[iDb].zDbSName; const char *zTab = SCHEMA_TABLE(iDb); if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER; if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) || sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ return; } } #endif /* Generate code to destroy the database record of the trigger. */ if( (v = sqlite3GetVdbe(pParse))!=0 ){ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'", db->aDb[iDb].zDbSName, MASTER_NAME, pTrigger->zName ); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); |
︙ | ︙ | |||
650 651 652 653 654 655 656 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pHash = &(db->aDb[iDb].pSchema->trigHash); pTrigger = sqlite3HashInsert(pHash, zName, 0); if( ALWAYS(pTrigger) ){ if( pTrigger->pSchema==pTrigger->pTabSchema ){ Table *pTab = tableOfTrigger(pTrigger); | > | | | > | 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pHash = &(db->aDb[iDb].pSchema->trigHash); pTrigger = sqlite3HashInsert(pHash, zName, 0); if( ALWAYS(pTrigger) ){ if( pTrigger->pSchema==pTrigger->pTabSchema ){ Table *pTab = tableOfTrigger(pTrigger); if( pTab ){ Trigger **pp; for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext)); *pp = (*pp)->pNext; } } sqlite3DeleteTrigger(db, pTrigger); db->mDbFlags |= DBFLAG_SchemaChange; } } /* |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
722 723 724 725 726 727 728 | if( aXRef[i]<0 && i!=pTab->iPKey ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); } } } if( !isView ){ | < < > > > > > > > > > > > > < < < < < < < < | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 | if( aXRef[i]<0 && i!=pTab->iPKey ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); } } } if( !isView ){ /* Do constraint checks. */ assert( regOldRowid>0 ); sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace, aXRef, 0); /* If REPLACE conflict handling may have been used, or if the PK of the ** row is changing, then the GenerateConstraintChecks() above may have ** moved cursor iDataCur. Reseek it. */ if( bReplace || chngKey ){ if( pPk ){ sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey); }else{ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid); } VdbeCoverageNeverTaken(v); } /* Do FK constraint checks. */ if( hasFK ){ sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey); } /* Delete the index entries associated with the current record. */ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1); /* If changing the rowid value, or if there are foreign key constraints ** to process, delete the old record. Otherwise, add a noop OP_Delete ** to invoke the pre-update hook. ** ** That (regNew==regnewRowid+1) is true is also important for the |
︙ | ︙ | |||
773 774 775 776 777 778 779 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); } #else if( hasFK>1 || chngKey ){ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); } #endif | < < < | 775 776 777 778 779 780 781 782 783 784 785 786 787 788 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); } #else if( hasFK>1 || chngKey ){ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); } #endif if( hasFK ){ sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey); } /* Insert the new index entries and the new record. */ sqlite3CompleteInsertion( |
︙ | ︙ |
Changes to src/upsert.c.
︙ | ︙ | |||
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | 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; | > < > > > > > > | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | Index *pIdx, /* The UNIQUE constraint that failed */ int iCur /* Cursor for pIdx (or pTab if pIdx==NULL) */ ){ Vdbe *v = pParse->pVdbe; sqlite3 *db = pParse->db; SrcList *pSrc; /* FROM clause for the UPDATE */ int iDataCur; int i; 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; pParse->nMem += nPk; for(i=0; i<nPk; i++){ int k; assert( pPk->aiColumn[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); /* excluded.* columns of type REAL need to be converted to a hard real */ for(i=0; i<pTab->nCol; i++){ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, pUpsert->regData+i); } } sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet, pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert); pUpsert->pUpsertSet = 0; /* Will have been deleted by sqlite3Update() */ pUpsert->pUpsertWhere = 0; /* Will have been deleted by sqlite3Update() */ VdbeNoopComment((v, "End DO UPDATE of UPSERT")); } #endif /* SQLITE_OMIT_UPSERT */ |
Changes to src/util.c.
︙ | ︙ | |||
1494 1495 1496 1497 1498 1499 1500 | memcpy(&a, &x, 8); e = (a>>52) - 1022; return e*10; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ | | | | 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 | memcpy(&a, &x, 8); e = (a>>52) - 1022; return e*10; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ defined(SQLITE_ENABLE_STAT4) || \ defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) /* ** Convert a LogEst into an integer. ** ** Note that this routine is only used when one or more of various ** non-standard compile-time options is enabled. */ u64 sqlite3LogEstToInt(LogEst x){ u64 n; n = x%10; x /= 10; if( n>=5 ) n -= 2; else if( n>=1 ) n -= 1; #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) if( x>60 ) return (u64)LARGEST_INT64; #else /* If only SQLITE_ENABLE_STAT4 is on, then the largest input ** possible to this routine is 310, resulting in a maximum x of 31 */ assert( x<=60 ); #endif return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x); } #endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */ |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
339 340 341 342 343 344 345 346 347 348 349 350 351 352 | ** always preferred, even if the affinity is REAL, because ** an integer representation is more space efficient on disk. ** ** SQLITE_AFF_TEXT: ** Convert pRec to a text representation. ** ** SQLITE_AFF_BLOB: ** No-op. pRec is unchanged. */ static void applyAffinity( Mem *pRec, /* The value to apply affinity to */ char affinity, /* The affinity to be applied */ u8 enc /* Use this text encoding */ ){ | > | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | ** always preferred, even if the affinity is REAL, because ** an integer representation is more space efficient on disk. ** ** SQLITE_AFF_TEXT: ** Convert pRec to a text representation. ** ** SQLITE_AFF_BLOB: ** SQLITE_AFF_NONE: ** No-op. pRec is unchanged. */ static void applyAffinity( Mem *pRec, /* The value to apply affinity to */ char affinity, /* The affinity to be applied */ u8 enc /* Use this text encoding */ ){ |
︙ | ︙ | |||
480 481 482 483 484 485 486 | assert( (f & (MEM_Static|MEM_Dyn))==0 ); }else{ c = 's'; } *(zCsr++) = c; sqlite3_snprintf(100, zCsr, "%d[", pMem->n); zCsr += sqlite3Strlen30(zCsr); | | > | | 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | assert( (f & (MEM_Static|MEM_Dyn))==0 ); }else{ c = 's'; } *(zCsr++) = c; sqlite3_snprintf(100, zCsr, "%d[", pMem->n); zCsr += sqlite3Strlen30(zCsr); for(i=0; i<25 && i<pMem->n; i++){ sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF)); zCsr += sqlite3Strlen30(zCsr); } *zCsr++ = '|'; for(i=0; i<25 && i<pMem->n; i++){ char z = pMem->z[i]; if( z<32 || z>126 ) *zCsr++ = '.'; else *zCsr++ = z; } *(zCsr++) = ']'; if( f & MEM_Zero ){ sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero); |
︙ | ︙ | |||
514 515 516 517 518 519 520 | }else{ zBuf[1] = 's'; } k = 2; sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n); k += sqlite3Strlen30(&zBuf[k]); zBuf[k++] = '['; | | | 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 | }else{ zBuf[1] = 's'; } k = 2; sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n); k += sqlite3Strlen30(&zBuf[k]); zBuf[k++] = '['; for(j=0; j<25 && j<pMem->n; j++){ u8 c = pMem->z[j]; if( c>=0x20 && c<0x7f ){ zBuf[k++] = c; }else{ zBuf[k++] = '.'; } } |
︙ | ︙ | |||
1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 | */ case OP_RealAffinity: { /* in1 */ pIn1 = &aMem[pOp->p1]; if( pIn1->flags & (MEM_Int|MEM_IntReal) ){ testcase( pIn1->flags & MEM_Int ); testcase( pIn1->flags & MEM_IntReal ); sqlite3VdbeMemRealify(pIn1); } break; } #endif #ifndef SQLITE_OMIT_CAST /* Opcode: Cast P1 P2 * * * | > | 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 | */ case OP_RealAffinity: { /* in1 */ pIn1 = &aMem[pOp->p1]; if( pIn1->flags & (MEM_Int|MEM_IntReal) ){ testcase( pIn1->flags & MEM_Int ); testcase( pIn1->flags & MEM_IntReal ); sqlite3VdbeMemRealify(pIn1); REGISTER_TRACE(pOp->p1, pIn1); } break; } #endif #ifndef SQLITE_OMIT_CAST /* Opcode: Cast P1 P2 * * * |
︙ | ︙ | |||
2222 2223 2224 2225 2226 2227 2228 | idx = aPermute ? aPermute[i] : i; assert( memIsValid(&aMem[p1+idx]) ); assert( memIsValid(&aMem[p2+idx]) ); REGISTER_TRACE(p1+idx, &aMem[p1+idx]); REGISTER_TRACE(p2+idx, &aMem[p2+idx]); assert( i<pKeyInfo->nKeyField ); pColl = pKeyInfo->aColl[i]; | | > > > > > | 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 | idx = aPermute ? aPermute[i] : i; assert( memIsValid(&aMem[p1+idx]) ); assert( memIsValid(&aMem[p2+idx]) ); REGISTER_TRACE(p1+idx, &aMem[p1+idx]); REGISTER_TRACE(p2+idx, &aMem[p2+idx]); assert( i<pKeyInfo->nKeyField ); pColl = pKeyInfo->aColl[i]; bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC); iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); if( iCompare ){ if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null)) ){ iCompare = -iCompare; } if( bRev ) iCompare = -iCompare; break; } } break; } |
︙ | ︙ | |||
2515 2516 2517 2518 2519 2520 2521 | ** ** The value extracted is stored in register P3. ** ** If the record contains fewer than P2 fields, then extract a NULL. Or, ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. ** | < < < < < | 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 | ** ** The value extracted is stored in register P3. ** ** If the record contains fewer than P2 fields, then extract a NULL. Or, ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. ** ** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then ** the result is guaranteed to only be used as the argument of a length() ** or typeof() function, respectively. The loading of large blobs can be ** skipped for length() and all content loading can be skipped for typeof(). */ case OP_Column: { int p2; /* column number to retrieve */ |
︙ | ︙ | |||
2808 2809 2810 2811 2812 2813 2814 | const char *zAffinity; /* The affinity to be applied */ zAffinity = pOp->p4.z; assert( zAffinity!=0 ); assert( pOp->p2>0 ); assert( zAffinity[pOp->p2]==0 ); pIn1 = &aMem[pOp->p1]; | | | > > | > > > > > | | > > > > > | 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 | const char *zAffinity; /* The affinity to be applied */ zAffinity = pOp->p4.z; assert( zAffinity!=0 ); assert( pOp->p2>0 ); assert( zAffinity[pOp->p2]==0 ); pIn1 = &aMem[pOp->p1]; while( 1 /*exit-by-break*/ ){ assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); assert( memIsValid(pIn1) ); applyAffinity(pIn1, zAffinity[0], encoding); if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){ /* When applying REAL affinity, if the result is still an MEM_Int ** that will fit in 6 bytes, then change the type to MEM_IntReal ** so that we keep the high-resolution integer value but know that ** the type really wants to be REAL. */ testcase( pIn1->u.i==140737488355328LL ); testcase( pIn1->u.i==140737488355327LL ); testcase( pIn1->u.i==-140737488355328LL ); testcase( pIn1->u.i==-140737488355329LL ); if( pIn1->u.i<=140737488355327LL && pIn1->u.i>=-140737488355328LL ){ pIn1->flags |= MEM_IntReal; pIn1->flags &= ~MEM_Int; }else{ pIn1->u.r = (double)pIn1->u.i; pIn1->flags |= MEM_Real; pIn1->flags &= ~MEM_Int; } } REGISTER_TRACE((int)(pIn1-aMem), pIn1); zAffinity++; if( zAffinity[0]==0 ) break; pIn1++; } break; |
︙ | ︙ | |||
2923 2924 2925 2926 2927 2928 2929 | pLast--; nField--; } } #endif /* Loop through the elements that will make up the record to figure | | > > > > > > > > > > > > > > > > > > > > > > > | | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > | | < | | | < < | | > | 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 | pLast--; nField--; } } #endif /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. After this loop, ** the Mem.uTemp field of each term should hold the serial-type that will ** be used for that term in the generated record: ** ** Mem.uTemp value type ** --------------- --------------- ** 0 NULL ** 1 1-byte signed integer ** 2 2-byte signed integer ** 3 3-byte signed integer ** 4 4-byte signed integer ** 5 6-byte signed integer ** 6 8-byte signed integer ** 7 IEEE float ** 8 Integer constant 0 ** 9 Integer constant 1 ** 10,11 reserved for expansion ** N>=12 and even BLOB ** N>=13 and odd text ** ** The following additional values are computed: ** nHdr Number of bytes needed for the record header ** nData Number of bytes of data space needed for the record ** nZero Zero bytes at the end of the record */ pRec = pLast; do{ assert( memIsValid(pRec) ); if( pRec->flags & MEM_Null ){ if( pRec->flags & MEM_Zero ){ /* 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 ); pRec->uTemp = 10; }else{ pRec->uTemp = 0; } nHdr++; }else if( pRec->flags & (MEM_Int|MEM_IntReal) ){ /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */ i64 i = pRec->u.i; u64 uu; testcase( pRec->flags & MEM_Int ); testcase( pRec->flags & MEM_IntReal ); if( i<0 ){ uu = ~i; }else{ uu = i; } nHdr++; testcase( uu==127 ); testcase( uu==128 ); testcase( uu==32767 ); testcase( uu==32768 ); testcase( uu==8388607 ); testcase( uu==8388608 ); testcase( uu==2147483647 ); testcase( uu==2147483648 ); testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL ); if( uu<=127 ){ if( (i&1)==i && file_format>=4 ){ pRec->uTemp = 8+(u32)uu; }else{ nData++; pRec->uTemp = 1; } }else if( uu<=32767 ){ nData += 2; pRec->uTemp = 2; }else if( uu<=8388607 ){ nData += 3; pRec->uTemp = 3; }else if( uu<=2147483647 ){ nData += 4; pRec->uTemp = 4; }else if( uu<=140737488355327LL ){ nData += 6; pRec->uTemp = 5; }else{ nData += 8; if( pRec->flags & MEM_IntReal ){ /* If the value is IntReal and is going to take up 8 bytes to store ** as an integer, then we might as well make it an 8-byte floating ** point value */ pRec->u.r = (double)pRec->u.i; pRec->flags &= ~MEM_IntReal; pRec->flags |= MEM_Real; pRec->uTemp = 7; }else{ pRec->uTemp = 6; } } }else if( pRec->flags & MEM_Real ){ nHdr++; nData += 8; pRec->uTemp = 7; }else{ assert( db->mallocFailed || pRec->flags&(MEM_Str|MEM_Blob) ); assert( pRec->n>=0 ); len = (u32)pRec->n; serial_type = (len*2) + 12 + ((pRec->flags & MEM_Str)!=0); if( pRec->flags & MEM_Zero ){ serial_type += pRec->u.nZero*2; if( nData ){ if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem; len += pRec->u.nZero; }else{ nZero += pRec->u.nZero; } } nData += len; nHdr += sqlite3VarintLen(serial_type); pRec->uTemp = serial_type; } if( pRec==pData0 ) break; pRec--; }while(1); /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint ** which determines the total number of bytes in the header. The varint ** value is the size of the header in bytes including the size varint |
︙ | ︙ | |||
3305 3306 3307 3308 3309 3310 3311 | (!desiredAutoCommit)?"cannot start a transaction within a transaction":( (iRollback)?"cannot rollback - no transaction is active": "cannot commit - no transaction is active")); rc = SQLITE_ERROR; goto abort_due_to_error; } | | | 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 | (!desiredAutoCommit)?"cannot start a transaction within a transaction":( (iRollback)?"cannot rollback - no transaction is active": "cannot commit - no transaction is active")); rc = SQLITE_ERROR; goto abort_due_to_error; } /*NOTREACHED*/ assert(0); } /* Opcode: Transaction P1 P2 P3 P4 P5 ** ** Begin a transaction on database P1 if a transaction is not already ** active. ** If P2 is non-zero, then a write-transaction is started, or if a |
︙ | ︙ | |||
4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 | #ifdef SQLITE_DEBUG pC->seekOp = pOp->opcode; #endif pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; if( pC->isTable ){ /* The BTREE_SEEK_EQ flag is only set on index cursors */ assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 || CORRUPT_DB ); /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so convert it. */ pIn3 = &aMem[pOp->p3]; | > > | | > > | | | | < > | 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 | #ifdef SQLITE_DEBUG pC->seekOp = pOp->opcode; #endif pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; if( pC->isTable ){ u16 flags3, newType; /* The BTREE_SEEK_EQ flag is only set on index cursors */ assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 || CORRUPT_DB ); /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so convert it. */ pIn3 = &aMem[pOp->p3]; flags3 = pIn3->flags; if( (flags3 & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn3, 0); } iKey = sqlite3VdbeIntValue(pIn3); /* Get the integer key value */ newType = pIn3->flags; /* Record the type after applying numeric affinity */ pIn3->flags = flags3; /* But convert the type back to its original */ /* If the P3 value could not be converted into an integer without ** loss of information, then special processing is required... */ if( (newType & (MEM_Int|MEM_IntReal))==0 ){ if( (newType & MEM_Real)==0 ){ if( (newType & MEM_Null) || oc>=OP_SeekGE ){ VdbeBranchTaken(1,2); goto jump_to_p2; }else{ rc = sqlite3BtreeLast(pC->uc.pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; goto seek_not_found; } }else |
︙ | ︙ | |||
5368 5369 5370 5371 5372 5373 5374 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found. ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ assert( pOp->opcode!=OP_Next || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE | | | > | | 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found. ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ assert( pOp->opcode!=OP_Next || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid || pC->seekOp==OP_IfNoHope); assert( pOp->opcode!=OP_Prev || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope || pC->seekOp==OP_NullRow); rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3); next_tail: pC->cacheStatus = CACHE_STALE; VdbeBranchTaken(rc==SQLITE_OK,2); if( rc==SQLITE_OK ){ |
︙ | ︙ | |||
5891 5892 5893 5894 5895 5896 5897 | { zMaster = MASTER_NAME; initData.db = db; initData.iDb = iDb; initData.pzErrMsg = &p->zErrMsg; initData.mInitFlags = 0; zSql = sqlite3MPrintf(db, | | | 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 | { zMaster = MASTER_NAME; initData.db = db; initData.iDb = iDb; initData.pzErrMsg = &p->zErrMsg; initData.mInitFlags = 0; zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\".%s WHERE %s ORDER BY rowid", db->aDb[iDb].zDbSName, zMaster, pOp->p4.z); if( zSql==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ assert( db->init.busy==0 ); db->init.busy = 1; initData.rc = SQLITE_OK; |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
218 219 220 221 222 223 224 | #endif #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) void sqlite3ExplainBreakpoint(const char*,const char*); #else # define sqlite3ExplainBreakpoint(A,B) /*no-op*/ #endif void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); | | | | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | #endif #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) void sqlite3ExplainBreakpoint(const char*,const char*); #else # define sqlite3ExplainBreakpoint(A,B) /*no-op*/ #endif void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8); void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3); void sqlite3VdbeChangeP5(Vdbe*, u16 P5); void sqlite3VdbeJumpHere(Vdbe*, int addr); int sqlite3VdbeChangeToNoop(Vdbe*, int addr); int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type); void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
482 483 484 485 486 487 488 | void sqlite3VdbeError(Vdbe*, const char *, ...); void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); int sqlite3VdbeCursorMoveto(VdbeCursor**, int*); int sqlite3VdbeCursorRestore(VdbeCursor*); u32 sqlite3VdbeSerialTypeLen(u32); u8 sqlite3VdbeOneByteSerialTypeLen(u8); | < | 482 483 484 485 486 487 488 489 490 491 492 493 494 495 | void sqlite3VdbeError(Vdbe*, const char *, ...); void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); int sqlite3VdbeCursorMoveto(VdbeCursor**, int*); int sqlite3VdbeCursorRestore(VdbeCursor*); u32 sqlite3VdbeSerialTypeLen(u32); u8 sqlite3VdbeOneByteSerialTypeLen(u8); u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*); |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
840 841 842 843 844 845 846 | ** is requested more than once within the same run of a single prepared ** statement, the exact same time is returned for each invocation regardless ** of the amount of time that elapses between invocations. In other words, ** the time returned is always the time of the first call. */ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ int rc; | | | 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 | ** is requested more than once within the same run of a single prepared ** statement, the exact same time is returned for each invocation regardless ** of the amount of time that elapses between invocations. In other words, ** the time returned is always the time of the first call. */ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ int rc; #ifndef SQLITE_ENABLE_STAT4 sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime; assert( p->pVdbe!=0 ); #else sqlite3_int64 iTime = 0; sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; #endif if( *piTime==0 ){ |
︙ | ︙ | |||
905 906 907 908 909 910 911 | ** auxiliary data pointers that is available to all functions within a ** single prepared statement. The iArg values must match. */ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ AuxData *pAuxData; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); | | | 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 | ** auxiliary data pointers that is available to all functions within a ** single prepared statement. The iArg values must match. */ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ AuxData *pAuxData; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #if SQLITE_ENABLE_STAT4 if( pCtx->pVdbe==0 ) return 0; #else assert( pCtx->pVdbe!=0 ); #endif for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){ if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){ return pAuxData->pAux; |
︙ | ︙ | |||
939 940 941 942 943 944 945 | void *pAux, void (*xDelete)(void*) ){ AuxData *pAuxData; Vdbe *pVdbe = pCtx->pVdbe; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); | | | 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 | void *pAux, void (*xDelete)(void*) ){ AuxData *pAuxData; Vdbe *pVdbe = pCtx->pVdbe; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #ifdef SQLITE_ENABLE_STAT4 if( pVdbe==0 ) goto failed; #else assert( pVdbe!=0 ); #endif for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){ if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){ |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
973 974 975 976 977 978 979 | #endif /* ** Change the value of the opcode, or P1, P2, P3, or P5 operands ** for a specific instruction. */ | | | | | | 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 | #endif /* ** Change the value of the opcode, or P1, P2, P3, or P5 operands ** for a specific instruction. */ void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){ sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode; } void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ sqlite3VdbeGetOp(p,addr)->p1 = val; } void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ sqlite3VdbeGetOp(p,addr)->p2 = val; } void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ sqlite3VdbeGetOp(p,addr)->p3 = val; } void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ assert( p->nOp>0 || p->db->mallocFailed ); if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5; } |
︙ | ︙ | |||
1489 1490 1491 1492 1493 1494 1495 | StrAccum x; assert( nTemp>=20 ); sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0); switch( pOp->p4type ){ case P4_KEYINFO: { int j; KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; | | | | > > | 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 | StrAccum x; assert( nTemp>=20 ); sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0); switch( pOp->p4type ){ case P4_KEYINFO: { int j; KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; assert( pKeyInfo->aSortFlags!=0 ); sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField); for(j=0; j<pKeyInfo->nKeyField; j++){ CollSeq *pColl = pKeyInfo->aColl[j]; const char *zColl = pColl ? pColl->zName : ""; if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; sqlite3_str_appendf(&x, ",%s%s%s", (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_DESC) ? "-" : "", (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_BIGNULL)? "N." : "", zColl); } sqlite3_str_append(&x, ")", 1); break; } #ifdef SQLITE_ENABLE_CURSOR_HINTS case P4_EXPR: { displayP4Expr(&x, pOp->p4.pExpr); |
︙ | ︙ | |||
1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 | ** main program. */ pOp = &p->aOp[i]; }else{ /* We are currently listing subprograms. Figure out which one and ** pick up the appropriate opcode. */ int j; i -= p->nOp; for(j=0; i>=apSub[j]->nOp; j++){ i -= apSub[j]->nOp; } pOp = &apSub[j]->aOp[i]; } /* When an OP_Program opcode is encounter (the only opcode that has ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms ** kept in p->aMem[9].z to hold the new program - assuming this subprogram | > > > | 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 | ** main program. */ pOp = &p->aOp[i]; }else{ /* We are currently listing subprograms. Figure out which one and ** pick up the appropriate opcode. */ int j; i -= p->nOp; assert( apSub!=0 ); assert( nSub>0 ); for(j=0; i>=apSub[j]->nOp; j++){ i -= apSub[j]->nOp; assert( i<apSub[j]->nOp || j+1<nSub ); } pOp = &apSub[j]->aOp[i]; } /* When an OP_Program opcode is encounter (the only opcode that has ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms ** kept in p->aMem[9].z to hold the new program - assuming this subprogram |
︙ | ︙ | |||
3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 | ** N>=12 and even (N-12)/2 BLOB ** N>=13 and odd (N-13)/2 text ** ** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions ** of SQLite will not understand those serial types. */ /* ** Return the serial-type for the value stored in pMem. ** ** This routine might convert a large MEM_IntReal value into MEM_Real. */ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ int flags = pMem->flags; u32 n; assert( pLen!=0 ); if( flags&MEM_Null ){ | > > > > > > > | 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 | ** N>=12 and even (N-12)/2 BLOB ** N>=13 and odd (N-13)/2 text ** ** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions ** of SQLite will not understand those serial types. */ #if 0 /* Inlined into the OP_MakeRecord opcode */ /* ** Return the serial-type for the value stored in pMem. ** ** This routine might convert a large MEM_IntReal value into MEM_Real. ** ** 2019-07-11: The primary user of this subroutine was the OP_MakeRecord ** opcode in the byte-code engine. But by moving this routine in-line, we ** can omit some redundant tests and make that opcode a lot faster. So ** this routine is now only used by the STAT3 logic and STAT3 support has ** ended. The code is kept here for historical reference only. */ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ int flags = pMem->flags; u32 n; assert( pLen!=0 ); if( flags&MEM_Null ){ |
︙ | ︙ | |||
3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 | n = (u32)pMem->n; if( flags & MEM_Zero ){ n += pMem->u.nZero; } *pLen = n; return ((n*2) + 12 + ((flags&MEM_Str)!=0)); } /* ** The sizes for serial types less than 128 */ static const u8 sqlite3SmallTypeSizes[] = { /* 0 1 2 3 4 5 6 7 8 9 */ /* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, | > | 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 | n = (u32)pMem->n; if( flags & MEM_Zero ){ n += pMem->u.nZero; } *pLen = n; return ((n*2) + 12 + ((flags&MEM_Str)!=0)); } #endif /* inlined into OP_MakeRecord */ /* ** The sizes for serial types less than 128 */ static const u8 sqlite3SmallTypeSizes[] = { /* 0 1 2 3 4 5 6 7 8 9 */ /* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, |
︙ | ︙ | |||
3818 3819 3820 3821 3822 3823 3824 | ){ UnpackedRecord *p; /* Unpacked record to return */ int nByte; /* Number of bytes required for *p */ nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); if( !p ) return 0; p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; | | | 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 | ){ UnpackedRecord *p; /* Unpacked record to return */ int nByte; /* Number of bytes required for *p */ nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); if( !p ) return 0; p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; assert( pKeyInfo->aSortFlags!=0 ); p->pKeyInfo = pKeyInfo; p->nField = pKeyInfo->nKeyField + 1; return p; } /* ** Given the nKey-byte encoding of a record in pKey[], populate the |
︙ | ︙ | |||
3917 3918 3919 3920 3921 3922 3923 | */ /* mem1.u.i = 0; // not needed, here to silence compiler warning */ idx1 = getVarint32(aKey1, szHdr1); if( szHdr1>98307 ) return SQLITE_CORRUPT; d1 = szHdr1; assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); | | | 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 | */ /* mem1.u.i = 0; // not needed, here to silence compiler warning */ idx1 = getVarint32(aKey1, szHdr1); if( szHdr1>98307 ) return SQLITE_CORRUPT; d1 = szHdr1; assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); assert( pKeyInfo->aSortFlags!=0 ); assert( pKeyInfo->nKeyField>0 ); assert( idx1<=szHdr1 || CORRUPT_DB ); do{ u32 serial_type1; /* Read the serial types for the next element in each key. */ idx1 += getVarint32( aKey1+idx1, serial_type1 ); |
︙ | ︙ | |||
3948 3949 3950 3951 3952 3953 3954 | /* Do the comparison */ rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0); if( rc!=0 ){ assert( mem1.szMalloc==0 ); /* See comment below */ | > > > > > | | 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 | /* Do the comparison */ rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0); if( rc!=0 ){ assert( mem1.szMalloc==0 ); /* See comment below */ if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) && ((mem1.flags & MEM_Null) || (pPKey2->aMem[i].flags & MEM_Null)) ){ rc = -rc; } if( pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC ){ rc = -rc; /* Invert the result for DESC sort order. */ } goto debugCompareEnd; } i++; }while( idx1<szHdr1 && i<pPKey2->nField ); |
︙ | ︙ | |||
4324 4325 4326 4327 4328 4329 4330 | pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; return 0; /* Corruption */ } VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); | | | 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 | pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; return 0; /* Corruption */ } VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); assert( pPKey2->pKeyInfo->aSortFlags!=0 ); assert( pPKey2->pKeyInfo->nKeyField>0 ); assert( idx1<=szHdr1 || CORRUPT_DB ); do{ u32 serial_type; /* RHS is an integer */ if( pRhs->flags & (MEM_Int|MEM_IntReal) ){ |
︙ | ︙ | |||
4447 4448 4449 4450 4451 4452 4453 | /* RHS is null */ else{ serial_type = aKey1[idx1]; rc = (serial_type!=0); } if( rc!=0 ){ | | > > > > > | > | 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 | /* RHS is null */ else{ serial_type = aKey1[idx1]; rc = (serial_type!=0); } if( rc!=0 ){ int sortFlags = pPKey2->pKeyInfo->aSortFlags[i]; if( sortFlags ){ if( (sortFlags & KEYINFO_ORDER_BIGNULL)==0 || ((sortFlags & KEYINFO_ORDER_DESC) !=(serial_type==0 || (pRhs->flags&MEM_Null))) ){ rc = -rc; } } assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); assert( mem1.szMalloc==0 ); /* See comment below */ return rc; } i++; |
︙ | ︙ | |||
4616 4617 4618 4619 4620 4621 4622 | if( (szHdr + nStr) > nKey1 ){ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; return 0; /* Corruption */ } nCmp = MIN( pPKey2->aMem[0].n, nStr ); res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp); | | > > > > < < < < | 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 | if( (szHdr + nStr) > nKey1 ){ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; return 0; /* Corruption */ } nCmp = MIN( pPKey2->aMem[0].n, nStr ); res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp); if( res>0 ){ res = pPKey2->r2; }else if( res<0 ){ res = pPKey2->r1; }else{ res = nStr - pPKey2->aMem[0].n; if( res==0 ){ if( pPKey2->nField>1 ){ res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); }else{ res = pPKey2->default_rc; pPKey2->eqSeen = 1; } }else if( res>0 ){ res = pPKey2->r2; }else{ res = pPKey2->r1; } } } assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) || CORRUPT_DB || pPKey2->pKeyInfo->db->mallocFailed ); |
︙ | ︙ | |||
4665 4666 4667 4668 4669 4670 4671 | ** is an integer. ** ** The easiest way to enforce this limit is to consider only records with ** 13 fields or less. If the first field is an integer, the maximum legal ** header size is (12*5 + 1 + 1) bytes. */ if( p->pKeyInfo->nAllField<=13 ){ int flags = p->aMem[0].flags; | | > > > | 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 | ** is an integer. ** ** The easiest way to enforce this limit is to consider only records with ** 13 fields or less. If the first field is an integer, the maximum legal ** header size is (12*5 + 1 + 1) bytes. */ if( p->pKeyInfo->nAllField<=13 ){ int flags = p->aMem[0].flags; if( p->pKeyInfo->aSortFlags[0] ){ if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){ return sqlite3VdbeRecordCompare; } p->r1 = 1; p->r2 = -1; }else{ p->r1 = -1; p->r2 = 1; } if( (flags & MEM_Int) ){ |
︙ | ︙ | |||
4914 4915 4916 4917 4918 4919 4920 | ** ** OP_PureFunc means that the function must be deterministic, and should ** throw an error if it is given inputs that would make it non-deterministic. ** This routine is invoked by date/time functions that use non-deterministic ** features such as 'now'. */ int sqlite3NotPureFunc(sqlite3_context *pCtx){ | | | 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 | ** ** OP_PureFunc means that the function must be deterministic, and should ** throw an error if it is given inputs that would make it non-deterministic. ** This routine is invoked by date/time functions that use non-deterministic ** features such as 'now'. */ int sqlite3NotPureFunc(sqlite3_context *pCtx){ #ifdef SQLITE_ENABLE_STAT4 if( pCtx->pVdbe==0 ) return 1; #endif if( pCtx->pVdbe->aOp[pCtx->iOp].opcode==OP_PureFunc ){ sqlite3_result_error(pCtx, "non-deterministic function in index expression or CHECK constraint", -1); return 0; |
︙ | ︙ | |||
5011 5012 5013 5014 5015 5016 5017 | preupdate.v = v; preupdate.pCsr = pCsr; preupdate.op = op; preupdate.iNewReg = iReg; preupdate.keyinfo.db = db; preupdate.keyinfo.enc = ENC(db); preupdate.keyinfo.nKeyField = pTab->nCol; | | | 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 | preupdate.v = v; preupdate.pCsr = pCsr; preupdate.op = op; preupdate.iNewReg = iReg; preupdate.keyinfo.db = db; preupdate.keyinfo.enc = ENC(db); preupdate.keyinfo.nKeyField = pTab->nCol; preupdate.keyinfo.aSortFlags = (u8*)&fakeSortOrder; preupdate.iKey1 = iKey1; preupdate.iKey2 = iKey2; preupdate.pTab = pTab; db->pPreUpdate = &preupdate; db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); db->pPreUpdate = 0; |
︙ | ︙ |
Changes to src/vdbeblob.c.
︙ | ︙ | |||
351 352 353 354 355 356 357 358 359 | */ int sqlite3_blob_close(sqlite3_blob *pBlob){ Incrblob *p = (Incrblob *)pBlob; int rc; sqlite3 *db; if( p ){ db = p->db; sqlite3_mutex_enter(db->mutex); | > < > | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | */ int sqlite3_blob_close(sqlite3_blob *pBlob){ Incrblob *p = (Incrblob *)pBlob; int rc; sqlite3 *db; if( p ){ sqlite3_stmt *pStmt = p->pStmt; db = p->db; sqlite3_mutex_enter(db->mutex); sqlite3DbFree(db, p); sqlite3_mutex_leave(db->mutex); rc = sqlite3_finalize(pStmt); }else{ rc = SQLITE_OK; } return rc; } /* |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
1299 1300 1301 1302 1303 1304 1305 | ** Otherwise, if the second argument is non-zero, then this function is ** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not ** already been allocated, allocate the UnpackedRecord structure that ** that function will return to its caller here. Then return a pointer to ** an sqlite3_value within the UnpackedRecord.a[] array. */ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ | | | 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 | ** Otherwise, if the second argument is non-zero, then this function is ** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not ** already been allocated, allocate the UnpackedRecord structure that ** that function will return to its caller here. Then return a pointer to ** an sqlite3_value within the UnpackedRecord.a[] array. */ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ #ifdef SQLITE_ENABLE_STAT4 if( p ){ UnpackedRecord *pRec = p->ppRec[0]; if( pRec==0 ){ Index *pIdx = p->pIdx; /* Index being probed */ int nByte; /* Bytes of space to allocate */ int i; /* Counter variable */ |
︙ | ︙ | |||
1335 1336 1337 1338 1339 1340 1341 | } pRec->nField = p->iVal+1; return &pRec->aMem[p->iVal]; } #else UNUSED_PARAMETER(p); | | | 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 | } pRec->nField = p->iVal+1; return &pRec->aMem[p->iVal]; } #else UNUSED_PARAMETER(p); #endif /* defined(SQLITE_ENABLE_STAT4) */ return sqlite3ValueNew(db); } /* ** The expression object indicated by the second argument is guaranteed ** to be a scalar SQL function. If ** |
︙ | ︙ | |||
1359 1360 1361 1362 1363 1364 1365 | ** If the result is a text value, the sqlite3_value object uses encoding ** enc. ** ** If the conditions above are not met, this function returns SQLITE_OK ** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to ** NULL and an SQLite error code returned. */ | | | 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 | ** If the result is a text value, the sqlite3_value object uses encoding ** enc. ** ** If the conditions above are not met, this function returns SQLITE_OK ** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to ** NULL and an SQLite error code returned. */ #ifdef SQLITE_ENABLE_STAT4 static int valueFromFunction( sqlite3 *db, /* The database connection */ Expr *p, /* The expression to evaluate */ u8 enc, /* Encoding to use */ u8 aff, /* Affinity to use */ sqlite3_value **ppVal, /* Write the new value here */ struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ |
︙ | ︙ | |||
1442 1443 1444 1445 1446 1447 1448 | } *ppVal = pVal; return rc; } #else # define valueFromFunction(a,b,c,d,e,f) SQLITE_OK | | | 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 | } *ppVal = pVal; return rc; } #else # define valueFromFunction(a,b,c,d,e,f) SQLITE_OK #endif /* defined(SQLITE_ENABLE_STAT4) */ /* ** Extract a value from the supplied expression in the manner described ** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object ** using valueNew(). ** ** If pCtx is NULL and an error occurs after the sqlite3_value object |
︙ | ︙ | |||
1471 1472 1473 1474 1475 1476 1477 | sqlite3_value *pVal = 0; int negInt = 1; const char *zNeg = ""; int rc = SQLITE_OK; assert( pExpr!=0 ); while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft; | | | 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 | sqlite3_value *pVal = 0; int negInt = 1; const char *zNeg = ""; int rc = SQLITE_OK; assert( pExpr!=0 ); while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft; #if defined(SQLITE_ENABLE_STAT4) if( 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 |
︙ | ︙ | |||
1564 1565 1566 1567 1568 1569 1570 | zVal = &pExpr->u.zToken[2]; nVal = sqlite3Strlen30(zVal)-1; assert( zVal[nVal]=='\'' ); sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, 0, SQLITE_DYNAMIC); } #endif | | | | | 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 | zVal = &pExpr->u.zToken[2]; nVal = sqlite3Strlen30(zVal)-1; assert( zVal[nVal]=='\'' ); sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, 0, SQLITE_DYNAMIC); } #endif #ifdef SQLITE_ENABLE_STAT4 else if( op==TK_FUNCTION && pCtx!=0 ){ rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx); } #endif else if( op==TK_TRUEFALSE ){ pVal = valueNew(db, pCtx); if( pVal ){ pVal->flags = MEM_Int; pVal->u.i = pExpr->u.zToken[4]==0; } } *ppVal = pVal; return rc; no_mem: #ifdef SQLITE_ENABLE_STAT4 if( pCtx==0 || pCtx->pParse->nErr==0 ) #endif sqlite3OomFault(db); sqlite3DbFree(db, zVal); assert( *ppVal==0 ); #ifdef SQLITE_ENABLE_STAT4 if( pCtx==0 ) sqlite3ValueFree(pVal); #else assert( pCtx==0 ); sqlite3ValueFree(pVal); #endif return SQLITE_NOMEM_BKPT; } |
︙ | ︙ | |||
1615 1616 1617 1618 1619 1620 1621 | u8 enc, /* Encoding to use */ u8 affinity, /* Affinity to use */ sqlite3_value **ppVal /* Write the new value here */ ){ return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0; } | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 | u8 enc, /* Encoding to use */ u8 affinity, /* Affinity to use */ sqlite3_value **ppVal /* Write the new value here */ ){ return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0; } #ifdef SQLITE_ENABLE_STAT4 /* ** Attempt to extract a value from pExpr and use it to construct *ppVal. ** ** If pAlloc is not NULL, then an UnpackedRecord object is created for ** pAlloc if one does not exist and the new value is added to the ** UnpackedRecord object. ** |
︙ | ︙ |
Changes to src/vdbesort.c.
︙ | ︙ | |||
825 826 827 828 829 830 831 | if( res==0 ){ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ res = vdbeSorterCompareTail( pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 ); } }else{ | > | | 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 | if( res==0 ){ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ res = vdbeSorterCompareTail( pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 ); } }else{ assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ res = res * -1; } } return res; } |
︙ | ︙ | |||
893 894 895 896 897 898 899 | if( res==0 ){ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ res = vdbeSorterCompareTail( pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 ); } | | > | 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 | if( res==0 ){ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ res = vdbeSorterCompareTail( pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 ); } }else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); res = res * -1; } return res; } /* |
︙ | ︙ | |||
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 | pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT; } } if( pKeyInfo->nAllField<13 && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl) ){ pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT; } } return rc; } | > | 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 | pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT; } } if( pKeyInfo->nAllField<13 && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl) && (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0 ){ pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT; } } return rc; } |
︙ | ︙ | |||
1724 1725 1726 1727 1728 1729 1730 | if( rc==SQLITE_OK ){ if( i==nWorker ){ /* Use the foreground thread for this operation */ rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list); }else{ /* Launch a background thread for this operation */ | | | > > > | 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 | if( rc==SQLITE_OK ){ if( i==nWorker ){ /* Use the foreground thread for this operation */ rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list); }else{ /* Launch a background thread for this operation */ u8 *aMem; void *pCtx; assert( pTask!=0 ); assert( pTask->pThread==0 && pTask->bDone==0 ); assert( pTask->list.pList==0 ); assert( pTask->list.aMemory==0 || pSorter->list.aMemory!=0 ); aMem = pTask->list.aMemory; pCtx = (void*)pTask; pSorter->iPrev = (u8)(pTask - pSorter->aTask); pTask->list = pSorter->list; pSorter->list.pList = 0; pSorter->list.szPMA = 0; if( aMem ){ pSorter->list.aMemory = aMem; pSorter->nMemory = sqlite3MallocSize(aMem); |
︙ | ︙ |
Changes to src/vtab.c.
︙ | ︙ | |||
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | int bDeclared; /* True after sqlite3_declare_vtab() is called */ }; /* ** Construct and install a Module object for a virtual table. When this ** routine is called, it is guaranteed that all appropriate locks are held ** and the module is not already part of the connection. */ Module *sqlite3VtabCreateModule( sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ const sqlite3_module *pModule, /* The definition of the module */ void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ){ Module *pMod; | > > > > > > > > > | | | | | < > | > > | | | > > > < < < | < | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | int bDeclared; /* True after sqlite3_declare_vtab() is called */ }; /* ** Construct and install a Module object for a virtual table. When this ** routine is called, it is guaranteed that all appropriate locks are held ** and the module is not already part of the connection. ** ** If there already exists a module with zName, replace it with the new one. ** If pModule==0, then delete the module zName if it exists. */ Module *sqlite3VtabCreateModule( sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ const sqlite3_module *pModule, /* The definition of the module */ void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ){ Module *pMod; Module *pDel; char *zCopy; if( pModule==0 ){ zCopy = (char*)zName; pMod = 0; }else{ int nName = sqlite3Strlen30(zName); pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1); if( pMod==0 ){ sqlite3OomFault(db); return 0; } zCopy = (char *)(&pMod[1]); memcpy(zCopy, zName, nName+1); pMod->zName = zCopy; pMod->pModule = pModule; pMod->pAux = pAux; pMod->xDestroy = xDestroy; pMod->pEpoTab = 0; pMod->nRefModule = 1; } pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); if( pDel ){ if( pDel==pMod ){ sqlite3OomFault(db); sqlite3DbFree(db, pDel); pMod = 0; }else{ sqlite3VtabEponymousTableClear(db, pDel); sqlite3VtabModuleUnref(db, pDel); } } return pMod; } /* ** The actual function that does the work of creating a new module. ** This function implements the sqlite3_create_module() and ** sqlite3_create_module_v2() interfaces. */ static int createModule( sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ const sqlite3_module *pModule, /* The definition of the module */ void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ){ int rc = SQLITE_OK; sqlite3_mutex_enter(db->mutex); (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); rc = sqlite3ApiExit(db, rc); if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); sqlite3_mutex_leave(db->mutex); return rc; } |
︙ | ︙ | |||
118 119 120 121 122 123 124 125 126 127 128 129 130 131 | void (*xDestroy)(void *) /* Module destructor function */ ){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; #endif return createModule(db, zName, pModule, pAux, xDestroy); } /* ** Lock the virtual table so that it cannot be disconnected. ** Locks nest. Every lock should have a corresponding unlock. ** If an unlock is omitted, resources leaks will occur. ** ** If a disconnect is attempted while a virtual table is locked, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | void (*xDestroy)(void *) /* Module destructor function */ ){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; #endif return createModule(db, zName, pModule, pAux, xDestroy); } /* ** External API to drop all virtual-table modules, except those named ** on the azNames list. */ int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ HashElem *pThis, *pNext; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){ Module *pMod = (Module*)sqliteHashData(pThis); pNext = sqliteHashNext(pThis); if( azNames ){ int ii; for(ii=0; azNames[ii]!=0 && strcmp(azNames[ii],pMod->zName)!=0; ii++){} if( azNames[ii]!=0 ) continue; } createModule(db, pMod->zName, 0, 0, 0); } return SQLITE_OK; } /* ** Decrement the reference count on a Module object. Destroy the ** module when the reference count reaches zero. */ void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){ assert( pMod->nRefModule>0 ); pMod->nRefModule--; if( pMod->nRefModule==0 ){ if( pMod->xDestroy ){ pMod->xDestroy(pMod->pAux); } assert( pMod->pEpoTab==0 ); sqlite3DbFree(db, pMod); } } /* ** Lock the virtual table so that it cannot be disconnected. ** Locks nest. Every lock should have a corresponding unlock. ** If an unlock is omitted, resources leaks will occur. ** ** If a disconnect is attempted while a virtual table is locked, |
︙ | ︙ | |||
158 159 160 161 162 163 164 165 166 167 168 169 170 171 | assert( db ); assert( pVTab->nRef>0 ); assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE ); pVTab->nRef--; if( pVTab->nRef==0 ){ sqlite3_vtab *p = pVTab->pVtab; if( p ){ p->pModule->xDisconnect(p); } sqlite3DbFree(db, pVTab); } } | > | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | assert( db ); assert( pVTab->nRef>0 ); assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE ); pVTab->nRef--; if( pVTab->nRef==0 ){ sqlite3_vtab *p = pVTab->pVtab; sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); if( p ){ p->pModule->xDisconnect(p); } sqlite3DbFree(db, pVTab); } } |
︙ | ︙ | |||
562 563 564 565 566 567 568 569 570 571 572 573 574 575 | } sqlite3DbFree(db, pVTable); }else if( ALWAYS(pVTable->pVtab) ){ /* Justification of ALWAYS(): A correct vtab constructor must allocate ** the sqlite3_vtab object if successful. */ memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); pVTable->pVtab->pModule = pMod->pModule; pVTable->nRef = 1; if( sCtx.bDeclared==0 ){ const char *zFormat = "vtable constructor did not declare schema: %s"; *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); sqlite3VtabUnlock(pVTable); rc = SQLITE_ERROR; }else{ | > | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | } sqlite3DbFree(db, pVTable); }else if( ALWAYS(pVTable->pVtab) ){ /* Justification of ALWAYS(): A correct vtab constructor must allocate ** the sqlite3_vtab object if successful. */ memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); pVTable->pVtab->pModule = pMod->pModule; pMod->nRefModule++; pVTable->nRef = 1; if( sCtx.bDeclared==0 ){ const char *zFormat = "vtable constructor did not declare schema: %s"; *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); sqlite3VtabUnlock(pVTable); rc = SQLITE_ERROR; }else{ |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 | bSync = (w.iSyncPoint==iOffset); testcase( bSync ); while( iOffset<w.iSyncPoint ){ rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset); if( rc ) return rc; iOffset += szFrame; nExtra++; } } if( bSync ){ assert( rc==SQLITE_OK ); rc = sqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags)); } } | > | 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 | bSync = (w.iSyncPoint==iOffset); testcase( bSync ); while( iOffset<w.iSyncPoint ){ rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset); if( rc ) return rc; iOffset += szFrame; nExtra++; assert( pLast!=0 ); } } if( bSync ){ assert( rc==SQLITE_OK ); rc = sqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags)); } } |
︙ | ︙ | |||
3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 | */ iFrame = pWal->hdr.mxFrame; for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){ if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue; iFrame++; rc = walIndexAppend(pWal, iFrame, p->pgno); } while( rc==SQLITE_OK && nExtra>0 ){ iFrame++; nExtra--; rc = walIndexAppend(pWal, iFrame, pLast->pgno); } if( rc==SQLITE_OK ){ | > | 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 | */ iFrame = pWal->hdr.mxFrame; for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){ if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue; iFrame++; rc = walIndexAppend(pWal, iFrame, p->pgno); } assert( pLast!=0 || nExtra==0 ); while( rc==SQLITE_OK && nExtra>0 ){ iFrame++; nExtra--; rc = walIndexAppend(pWal, iFrame, pLast->pgno); } if( rc==SQLITE_OK ){ |
︙ | ︙ |
Changes to src/walker.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | /* ** Walk all expressions linked into the list of Window objects passed ** as the second argument. */ static int walkWindowList(Walker *pWalker, Window *pList){ Window *pWin; for(pWin=pList; pWin; pWin=pWin->pNextWin){ | > | > | > | > > > > > > > > > > | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /* ** Walk all expressions linked into the list of Window objects passed ** as the second argument. */ static int walkWindowList(Walker *pWalker, Window *pList){ Window *pWin; for(pWin=pList; pWin; pWin=pWin->pNextWin){ int rc; rc = sqlite3WalkExprList(pWalker, pWin->pOrderBy); if( rc ) return WRC_Abort; rc = sqlite3WalkExprList(pWalker, pWin->pPartition); if( rc ) return WRC_Abort; rc = sqlite3WalkExpr(pWalker, pWin->pFilter); if( rc ) return WRC_Abort; /* The next two are purely for calls to sqlite3RenameExprUnmap() ** within sqlite3WindowOffsetExpr(). Because of constraints imposed ** by sqlite3WindowOffsetExpr(), they can never fail. The results do ** not matter anyhow. */ rc = sqlite3WalkExpr(pWalker, pWin->pStart); if( NEVER(rc) ) return WRC_Abort; rc = sqlite3WalkExpr(pWalker, pWin->pEnd); if( NEVER(rc) ) return WRC_Abort; } return WRC_Continue; } #endif /* ** Walk an expression tree. Invoke the callback once for each node |
︙ | ︙ | |||
59 60 61 62 63 64 65 66 67 68 69 | 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; | > > > | | | | | | > | 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 | 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 ){ assert( !ExprHasProperty(pExpr, EP_WinFunc) ); pExpr = pExpr->pRight; continue; }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ assert( !ExprHasProperty(pExpr, EP_WinFunc) ); if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; }else{ if( pExpr->x.pList ){ if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort; } #endif } } break; } return WRC_Continue; } int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue; |
︙ | ︙ | |||
112 113 114 115 116 117 118 119 | if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; #if !defined(SQLITE_OMIT_WINDOWFUNC) && !defined(SQLITE_OMIT_ALTERTABLE) { Parse *pParse = pWalker->pParse; if( pParse && IN_RENAME_OBJECT ){ int rc = walkWindowList(pWalker, p->pWinDefn); | > > < | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; #if !defined(SQLITE_OMIT_WINDOWFUNC) && !defined(SQLITE_OMIT_ALTERTABLE) { Parse *pParse = pWalker->pParse; if( pParse && IN_RENAME_OBJECT ){ /* The following may return WRC_Abort if there are unresolvable ** symbols (e.g. a table that does not exist) in a window definition. */ int rc = walkWindowList(pWalker, p->pWinDefn); return rc; } } #endif return WRC_Continue; } |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
249 250 251 252 253 254 255 | && (iColumn!=XN_EXPR || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft, pScan->pIdxExpr,iCur)==0) && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin)) ){ if( (pTerm->eOperator & WO_EQUIV)!=0 && pScan->nEquiv<ArraySize(pScan->aiCur) | | > | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | && (iColumn!=XN_EXPR || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft, pScan->pIdxExpr,iCur)==0) && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin)) ){ if( (pTerm->eOperator & WO_EQUIV)!=0 && pScan->nEquiv<ArraySize(pScan->aiCur) && (pX = sqlite3ExprSkipCollateAndLikely(pTerm->pExpr->pRight))->op ==TK_COLUMN ){ int j; for(j=0; j<pScan->nEquiv; j++){ if( pScan->aiCur[j]==pX->iTable && pScan->aiColumn[j]==pX->iColumn ){ break; } |
︙ | ︙ | |||
445 446 447 448 449 450 451 | Index *pIdx, /* Index to match column of */ int iCol /* Column of index to match */ ){ int i; const char *zColl = pIdx->azColl[iCol]; for(i=0; i<pList->nExpr; i++){ | | | 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | Index *pIdx, /* Index to match column of */ int iCol /* Column of index to match */ ){ int i; const char *zColl = pIdx->azColl[iCol]; for(i=0; i<pList->nExpr; i++){ Expr *p = sqlite3ExprSkipCollateAndLikely(pList->a[i].pExpr); if( p->op==TK_COLUMN && p->iColumn==pIdx->aiColumn[iCol] && p->iTable==iBase ){ CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr); if( 0==sqlite3StrICmp(pColl->zName, zColl) ){ return i; |
︙ | ︙ | |||
509 510 511 512 513 514 515 | pTab = pTabList->a[0].pTab; /* If any of the expressions is an IPK column on table iBase, then return ** true. Note: The (p->iTable==iBase) part of this test may be false if the ** current SELECT is a correlated sub-query. */ for(i=0; i<pDistinct->nExpr; i++){ | | | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | pTab = pTabList->a[0].pTab; /* If any of the expressions is an IPK column on table iBase, then return ** true. Note: The (p->iTable==iBase) part of this test may be false if the ** current SELECT is a correlated sub-query. */ for(i=0; i<pDistinct->nExpr; i++){ Expr *p = sqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr); if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1; } /* Loop through all indices on the table, checking each to see if it makes ** the DISTINCT qualifier redundant. It does so if: ** ** 1. The index is itself UNIQUE, and |
︙ | ︙ | |||
929 930 931 932 933 934 935 936 937 938 939 940 941 942 | */ nOrderBy = 0; if( pOrderBy ){ int n = pOrderBy->nExpr; for(i=0; i<n; i++){ Expr *pExpr = pOrderBy->a[i].pExpr; if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; } if( i==n){ nOrderBy = n; } } /* Allocate the sqlite3_index_info structure | > | 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | */ nOrderBy = 0; if( pOrderBy ){ int n = pOrderBy->nExpr; for(i=0; i<n; i++){ Expr *pExpr = pOrderBy->a[i].pExpr; if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) break; } if( i==n){ nOrderBy = n; } } /* Allocate the sqlite3_index_info structure |
︙ | ︙ | |||
1027 1028 1029 1030 1031 1032 1033 | } j++; } for(i=0; i<nOrderBy; i++){ Expr *pExpr = pOrderBy->a[i].pExpr; pIdxOrderBy[i].iColumn = pExpr->iColumn; | | | 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 | } j++; } for(i=0; i<nOrderBy; i++){ Expr *pExpr = pOrderBy->a[i].pExpr; pIdxOrderBy[i].iColumn = pExpr->iColumn; pIdxOrderBy[i].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC; } *pmNoOmit = mNoOmit; return pIdxInfo; } /* |
︙ | ︙ | |||
1073 1074 1075 1076 1077 1078 1079 | } sqlite3_free(pVtab->zErrMsg); pVtab->zErrMsg = 0; return rc; } #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ | | | 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 | } sqlite3_free(pVtab->zErrMsg); pVtab->zErrMsg = 0; return rc; } #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ #ifdef SQLITE_ENABLE_STAT4 /* ** Estimate the location of a particular key among all keys in an ** index. Store the results in aStat as follows: ** ** aStat[0] Est. number of rows less than pRec ** aStat[1] Est. number of rows equal to pRec ** |
︙ | ︙ | |||
1266 1267 1268 1269 1270 1271 1272 | aStat[1] = pIdx->aAvgEq[nField-1]; } /* Restore the pRec->nField value before returning. */ pRec->nField = nField; return i; } | | | 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 | aStat[1] = pIdx->aAvgEq[nField-1]; } /* Restore the pRec->nField value before returning. */ pRec->nField = nField; return i; } #endif /* SQLITE_ENABLE_STAT4 */ /* ** If it is not NULL, pTerm is a term that provides an upper or lower ** bound on a range scan. Without considering pTerm, it is estimated ** that the scan will visit nNew rows. This function returns the number ** estimated to be visited after taking pTerm into account. ** |
︙ | ︙ | |||
1292 1293 1294 1295 1296 1297 1298 | nRet -= 20; assert( 20==sqlite3LogEst(4) ); } } return nRet; } | | > | | 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 | nRet -= 20; assert( 20==sqlite3LogEst(4) ); } } return nRet; } #ifdef SQLITE_ENABLE_STAT4 /* ** Return the affinity for a single column of an index. */ char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){ assert( iCol>=0 && iCol<pIdx->nColumn ); if( !pIdx->zColAff ){ if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB; } assert( pIdx->zColAff[iCol]!=0 ); return pIdx->zColAff[iCol]; } #endif #ifdef SQLITE_ENABLE_STAT4 /* ** This function is called to estimate the number of rows visited by a ** range-scan on a skip-scan index. For example: ** ** CREATE INDEX i1 ON t1(a, b, c); ** SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?; ** |
︙ | ︙ | |||
1412 1413 1414 1415 1416 1417 1418 | sqlite3ValueFree(p1); sqlite3ValueFree(p2); sqlite3ValueFree(pVal); return rc; } | | | 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 | sqlite3ValueFree(p1); sqlite3ValueFree(p2); sqlite3ValueFree(pVal); return rc; } #endif /* SQLITE_ENABLE_STAT4 */ /* ** This function is used to estimate the number of rows that will be visited ** by scanning an index for a range of values. The range may have an upper ** bound, a lower bound, or both. The WHERE clause terms that set the upper ** and lower bounds are represented by pLower and pUpper respectively. For ** example, assuming that index p is on t1(a): |
︙ | ︙ | |||
1465 1466 1467 1468 1469 1470 1471 | WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ WhereLoop *pLoop /* Modify the .nOut and maybe .rRun fields */ ){ int rc = SQLITE_OK; int nOut = pLoop->nOut; LogEst nNew; | | | | | 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 | WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ WhereLoop *pLoop /* Modify the .nOut and maybe .rRun fields */ ){ int rc = SQLITE_OK; int nOut = pLoop->nOut; LogEst nNew; #ifdef SQLITE_ENABLE_STAT4 Index *p = pLoop->u.btree.pIndex; int nEq = pLoop->u.btree.nEq; if( p->nSample>0 && ALWAYS(nEq<p->nSampleCol) && OptimizationEnabled(pParse->db, SQLITE_Stat4) ){ if( nEq==pBuilder->nRecValid ){ UnpackedRecord *pRec = pBuilder->pRec; tRowcnt a[2]; int nBtm = pLoop->u.btree.nBtm; int nTop = pLoop->u.btree.nTop; |
︙ | ︙ | |||
1568 1569 1570 1571 1572 1573 1574 | pBuilder->pRec = pRec; if( rc==SQLITE_OK ){ if( iUpper>iLower ){ nNew = sqlite3LogEst(iUpper - iLower); /* TUNING: If both iUpper and iLower are derived from the same ** sample, then assume they are 4x more selective. This brings ** the estimated selectivity more in line with what it would be | | | 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 | pBuilder->pRec = pRec; if( rc==SQLITE_OK ){ if( iUpper>iLower ){ nNew = sqlite3LogEst(iUpper - iLower); /* TUNING: If both iUpper and iLower are derived from the same ** sample, then assume they are 4x more selective. This brings ** the estimated selectivity more in line with what it would be ** if estimated without the use of STAT4 tables. */ if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) ); }else{ nNew = 10; assert( 10==sqlite3LogEst(2) ); } if( nNew<nOut ){ nOut = nNew; } |
︙ | ︙ | |||
1617 1618 1619 1620 1621 1622 1623 | pLoop->nOut, nOut)); } #endif pLoop->nOut = (LogEst)nOut; return rc; } | | | | 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 | pLoop->nOut, nOut)); } #endif pLoop->nOut = (LogEst)nOut; return rc; } #ifdef SQLITE_ENABLE_STAT4 /* ** Estimate the number of rows that will be returned based on ** an equality constraint x=VALUE and where that VALUE occurs in ** the histogram data. This only works when x is the left-most ** column of an index and sqlite_stat4 histogram data is available ** for that index. When pExpr==NULL that means the constraint is ** "x IS NULL" instead of "x=VALUE". ** ** Write the estimated row count into *pnRow and return SQLITE_OK. ** If unable to make an estimate, leave *pnRow unchanged and return ** non-zero. ** |
︙ | ︙ | |||
1680 1681 1682 1683 1684 1685 1686 | whereKeyStats(pParse, p, pRec, 0, a); WHERETRACE(0x10,("equality scan regions %s(%d): %d\n", p->zName, nEq-1, (int)a[1])); *pnRow = a[1]; return rc; } | | | | 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 | whereKeyStats(pParse, p, pRec, 0, a); WHERETRACE(0x10,("equality scan regions %s(%d): %d\n", p->zName, nEq-1, (int)a[1])); *pnRow = a[1]; return rc; } #endif /* SQLITE_ENABLE_STAT4 */ #ifdef SQLITE_ENABLE_STAT4 /* ** Estimate the number of rows that will be returned based on ** an IN constraint where the right-hand side of the IN operator ** is a list of values. Example: ** ** WHERE x IN (1,2,3,4) ** |
︙ | ︙ | |||
1729 1730 1731 1732 1733 1734 1735 | if( nRowEst > nRow0 ) nRowEst = nRow0; *pnRow = nRowEst; WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst)); } assert( pBuilder->nRecValid==nRecValid ); return rc; } | | | 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 | if( nRowEst > nRow0 ) nRowEst = nRow0; *pnRow = nRowEst; WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst)); } assert( pBuilder->nRecValid==nRecValid ); return rc; } #endif /* SQLITE_ENABLE_STAT4 */ #ifdef WHERETRACE_ENABLED /* ** Print the content of a WhereTerm object */ static void whereTermPrint(WhereTerm *pTerm, int iTerm){ |
︙ | ︙ | |||
2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 | WhereTerm *pTerm, *pX; Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf); int i, j, k; LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */ assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; if( (pTerm->prereqAll & notAllowed)!=0 ) continue; for(j=pLoop->nLTerm-1; j>=0; j--){ pX = pLoop->aLTerm[j]; if( pX==0 ) continue; if( pX==pTerm ) break; | > | 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 | WhereTerm *pTerm, *pX; Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf); int i, j, k; LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */ assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ assert( pTerm!=0 ); if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; if( (pTerm->prereqAll & notAllowed)!=0 ) continue; for(j=pLoop->nLTerm-1; j>=0; j--){ pX = pLoop->aLTerm[j]; if( pX==0 ) continue; if( pX==pTerm ) break; |
︙ | ︙ | |||
2449 2450 2451 2452 2453 2454 2455 | rSize = pProbe->aiRowLogEst[0]; rLogSize = estLog(rSize); for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */ LogEst rCostIdx; LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */ int nIn = 0; | | | 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 | rSize = pProbe->aiRowLogEst[0]; rLogSize = estLog(rSize); for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */ LogEst rCostIdx; LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */ int nIn = 0; #ifdef SQLITE_ENABLE_STAT4 int nRecValid = pBuilder->nRecValid; #endif if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) && indexColumnNotNull(pProbe, saved_nEq) ){ continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ } |
︙ | ︙ | |||
2510 2511 2512 2513 2514 2515 2516 | ** first such term in use, and sets nIn back to 0 if it is not. */ for(i=0; i<pNew->nLTerm-1; i++){ if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0; } }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ /* "x IN (value, value, ...)" */ nIn = sqlite3LogEst(pExpr->x.pList->nExpr); | < < | 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 | ** first such term in use, and sets nIn back to 0 if it is not. */ for(i=0; i<pNew->nLTerm-1; i++){ if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0; } }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ /* "x IN (value, value, ...)" */ nIn = sqlite3LogEst(pExpr->x.pList->nExpr); } 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 |
︙ | ︙ | |||
2607 2608 2609 2610 2611 2612 2613 | /* At this point pNew->nOut is set to the number of rows expected to ** be visited by the index scan before considering term pTerm, or the ** values of nIn and nInMul. In other words, assuming that all ** "x IN(...)" terms are replaced with "x = ?". This block updates ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul). */ assert( pNew->nOut==saved_nOut ); if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ | | | | | 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 | /* At this point pNew->nOut is set to the number of rows expected to ** be visited by the index scan before considering term pTerm, or the ** values of nIn and nInMul. In other words, assuming that all ** "x IN(...)" terms are replaced with "x = ?". This block updates ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul). */ assert( pNew->nOut==saved_nOut ); if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ /* Adjust nOut using stat4 data. Or, if there is no stat4 ** data, using some other estimate. */ whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew); }else{ int nEq = ++pNew->u.btree.nEq; assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) ); assert( pNew->nOut==saved_nOut ); if( pTerm->truthProb<=0 && pProbe->aiColumn[saved_nEq]>=0 ){ assert( (eOp & WO_IN) || nIn==0 ); testcase( eOp & WO_IN ); pNew->nOut += pTerm->truthProb; pNew->nOut -= nIn; }else{ #ifdef SQLITE_ENABLE_STAT4 tRowcnt nOut = 0; if( nInMul==0 && pProbe->nSample && pNew->u.btree.nEq<=pProbe->nSampleCol && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)) && OptimizationEnabled(db, SQLITE_Stat4) ){ Expr *pExpr = pTerm->pExpr; if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){ testcase( eOp & WO_EQ ); testcase( eOp & WO_IS ); testcase( eOp & WO_ISNULL ); rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
︙ | ︙ | |||
2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 | } } /* Set rCostIdx to the cost of visiting selected rows in index. Add ** it to pNew->rRun, which is currently set to the cost of the index ** seek only. Then, if this is a non-covering index, add the cost of ** visiting the rows in the main table. */ rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); } ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); | > | 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 | } } /* Set rCostIdx to the cost of visiting selected rows in index. Add ** it to pNew->rRun, which is currently set to the cost of the index ** seek only. Then, if this is a non-covering index, add the cost of ** visiting the rows in the main table. */ assert( pSrc->pTab->szTabRow>0 ); rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); } ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); |
︙ | ︙ | |||
2689 2690 2691 2692 2693 2694 2695 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 && pNew->u.btree.nEq<pProbe->nColumn ){ whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); } pNew->nOut = saved_nOut; | | | 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 && pNew->u.btree.nEq<pProbe->nColumn ){ whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); } pNew->nOut = saved_nOut; #ifdef SQLITE_ENABLE_STAT4 pBuilder->nRecValid = nRecValid; #endif } pNew->prereq = saved_prereq; pNew->u.btree.nEq = saved_nEq; pNew->u.btree.nBtm = saved_nBtm; pNew->u.btree.nTop = saved_nTop; |
︙ | ︙ | |||
2762 2763 2764 2765 2766 2767 2768 | ExprList *pOB; ExprList *aColExpr; int ii, jj; if( pIndex->bUnordered ) return 0; if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0; for(ii=0; ii<pOB->nExpr; ii++){ | | | 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 | ExprList *pOB; ExprList *aColExpr; int ii, jj; if( pIndex->bUnordered ) return 0; if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0; for(ii=0; ii<pOB->nExpr; ii++){ Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){ if( pExpr->iColumn<0 ) return 1; for(jj=0; jj<pIndex->nKeyCol; jj++){ if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1; } }else if( (aColExpr = pIndex->aColExpr)!=0 ){ for(jj=0; jj<pIndex->nKeyCol; jj++){ |
︙ | ︙ | |||
2793 2794 2795 2796 2797 2798 2799 | Parse *pParse = pWC->pWInfo->pParse; while( pWhere->op==TK_AND ){ if( !whereUsablePartialIndex(iTab,pWC,pWhere->pLeft) ) return 0; pWhere = pWhere->pRight; } if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ | > > | | 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 | Parse *pParse = pWC->pWInfo->pParse; while( pWhere->op==TK_AND ){ if( !whereUsablePartialIndex(iTab,pWC,pWhere->pLeft) ) return 0; pWhere = pWhere->pRight; } if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ Expr *pExpr; if( pTerm->wtFlags & TERM_NOPARTIDX ) continue; pExpr = pTerm->pExpr; if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) ){ return 1; } } return 0; |
︙ | ︙ | |||
3062 3063 3064 3065 3066 3067 3068 | if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){ /* If a non-unique index is used, or if a prefix of the key for ** unique index is used (making the index functionally non-unique) ** then the sqlite_stat1 data becomes important for scoring the ** plan */ pTab->tabFlags |= TF_StatsUsed; } | | | 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 | if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){ /* If a non-unique index is used, or if a prefix of the key for ** unique index is used (making the index functionally non-unique) ** then the sqlite_stat1 data becomes important for scoring the ** plan */ pTab->tabFlags |= TF_StatsUsed; } #ifdef SQLITE_ENABLE_STAT4 sqlite3Stat4ProbeFree(pBuilder->pRec); pBuilder->nRecValid = 0; pBuilder->pRec = 0; #endif } return rc; } |
︙ | ︙ | |||
3690 3691 3692 3693 3694 3695 3696 | if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue; }else{ pLoop = pLast; } if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ if( pLoop->u.vtab.isOrdered ) obSat = obDone; break; | | | | | 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 | if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue; }else{ pLoop = pLast; } if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ if( pLoop->u.vtab.isOrdered ) obSat = obDone; break; }else if( wctrlFlags & WHERE_DISTINCTBY ){ pLoop->u.btree.nDistinctCol = 0; } iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor; /* Mark off any ORDER BY term X that is a column in the table of ** the current loop for which there is term in the WHERE ** clause of the form X IS NULL or X=? that reference only outer ** loops. */ for(i=0; i<nOrderBy; i++){ if( MASKBIT(i) & obSat ) continue; pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr); if( pOBExpr->op!=TK_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, ~ready, eqOpMask, 0); if( pTerm==0 ) continue; if( pTerm->eOperator==WO_IN ){ /* IN terms are only valid for sorting in the ORDER BY LIMIT |
︙ | ︙ | |||
3739 3740 3741 3742 3743 3744 3745 | return 0; }else{ nKeyCol = pIndex->nKeyCol; nColumn = pIndex->nColumn; assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); assert( pIndex->aiColumn[nColumn-1]==XN_ROWID || !HasRowid(pIndex->pTable)); | | > | > > > | > > | > | 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 | return 0; }else{ nKeyCol = pIndex->nKeyCol; nColumn = pIndex->nColumn; assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); assert( pIndex->aiColumn[nColumn-1]==XN_ROWID || !HasRowid(pIndex->pTable)); isOrderDistinct = IsUniqueIndex(pIndex) && (pLoop->wsFlags & WHERE_SKIPSCAN)==0; } /* Loop through all columns of the index and deal with the ones ** that are not constrained by == or IN. */ rev = revSet = 0; distinctColumns = 0; for(j=0; j<nColumn; j++){ u8 bOnce = 1; /* True to run the ORDER BY search loop */ assert( j>=pLoop->u.btree.nEq || (pLoop->aLTerm[j]==0)==(j<pLoop->nSkip) ); if( j<pLoop->u.btree.nEq && j>=pLoop->nSkip ){ u16 eOp = pLoop->aLTerm[j]->eOperator; /* Skip over == and IS and ISNULL terms. (Also skip IN terms when ** doing WHERE_ORDERBY_LIMIT processing). Except, IS and ISNULL ** terms imply that the index is not UNIQUE NOT NULL in which case ** the loop need to be marked as not order-distinct because it can ** have repeated NULL rows. ** ** If the current term is a column of an ((?,?) IN (SELECT...)) ** expression for which the SELECT returns more than one column, ** check that it is the only column used by this loop. Otherwise, ** if it is one of two or more, none of the columns can be ** considered to match an ORDER BY term. */ if( (eOp & eqOpMask)!=0 ){ if( eOp & (WO_ISNULL|WO_IS) ){ testcase( eOp & WO_ISNULL ); testcase( eOp & WO_IS ); testcase( isOrderDistinct ); isOrderDistinct = 0; } continue; }else if( ALWAYS(eOp & WO_IN) ){ /* ALWAYS() justification: eOp is an equality operator due to the ** j<pLoop->u.btree.nEq constraint above. Any equality other |
︙ | ︙ | |||
3791 3792 3793 3794 3795 3796 3797 | } /* Get the column number in the table (iColumn) and sort order ** (revIdx) for the j-th column of the index. */ if( pIndex ){ iColumn = pIndex->aiColumn[j]; | | | 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 | } /* Get the column number in the table (iColumn) and sort order ** (revIdx) for the j-th column of the index. */ if( pIndex ){ iColumn = pIndex->aiColumn[j]; revIdx = pIndex->aSortOrder[j] & KEYINFO_ORDER_DESC; if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID; }else{ iColumn = XN_ROWID; revIdx = 0; } /* An unconstrained column that might be NULL means that this |
︙ | ︙ | |||
3815 3816 3817 3818 3819 3820 3821 | /* Find the ORDER BY term that corresponds to the j-th column ** of the index and mark that ORDER BY term off */ isMatch = 0; for(i=0; bOnce && i<nOrderBy; i++){ if( MASKBIT(i) & obSat ) continue; | | > | > > | > | > > > > > > > | 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 | /* Find the ORDER BY term that corresponds to the j-th column ** of the index and mark that ORDER BY term off */ isMatch = 0; for(i=0; bOnce && i<nOrderBy; i++){ if( MASKBIT(i) & obSat ) continue; pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr); testcase( wctrlFlags & WHERE_GROUPBY ); testcase( wctrlFlags & WHERE_DISTINCTBY ); if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0; if( iColumn>=XN_ROWID ){ if( pOBExpr->op!=TK_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; if( pOBExpr->iColumn!=iColumn ) continue; }else{ Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr; if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){ continue; } } if( iColumn!=XN_ROWID ){ pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; } if( wctrlFlags & WHERE_DISTINCTBY ){ pLoop->u.btree.nDistinctCol = j+1; } isMatch = 1; break; } if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){ /* Make sure the sort order is compatible in an ORDER BY clause. ** Sort order is irrelevant for a GROUP BY clause. */ if( revSet ){ if( (rev ^ revIdx)!=(pOrderBy->a[i].sortFlags&KEYINFO_ORDER_DESC) ){ isMatch = 0; } }else{ rev = revIdx ^ (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC); if( rev ) *pRevMask |= MASKBIT(iLoop); revSet = 1; } } if( isMatch && (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL) ){ if( j==pLoop->u.btree.nEq ){ pLoop->wsFlags |= WHERE_BIGNULL_SORT; }else{ isMatch = 0; } } if( isMatch ){ if( iColumn==XN_ROWID ){ testcase( distinctColumns==0 ); distinctColumns = 1; } obSat |= MASKBIT(i); |
︙ | ︙ | |||
4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 | #if defined(WHERETRACE_ENABLED) if( sqlite3WhereTrace & 0xffff ){ sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags); if( wctrlFlags & WHERE_USE_LIMIT ){ sqlite3DebugPrintf(", limit: %d", iAuxArg); } sqlite3DebugPrintf(")\n"); } if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ sqlite3WhereClausePrint(sWLB.pWC); } #endif if( nTabList!=1 || whereShortCut(&sWLB)==0 ){ | > > > > > > > > > > | 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 | #if defined(WHERETRACE_ENABLED) if( sqlite3WhereTrace & 0xffff ){ sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags); if( wctrlFlags & WHERE_USE_LIMIT ){ sqlite3DebugPrintf(", limit: %d", iAuxArg); } sqlite3DebugPrintf(")\n"); if( sqlite3WhereTrace & 0x100 ){ Select sSelect; memset(&sSelect, 0, sizeof(sSelect)); sSelect.selFlags = SF_WhereBegin; sSelect.pSrc = pTabList; sSelect.pWhere = pWhere; sSelect.pOrderBy = pOrderBy; sSelect.pEList = pResultSet; sqlite3TreeViewSelect(0, &sSelect, 0); } } if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ sqlite3WhereClausePrint(sWLB.pWC); } #endif if( nTabList!=1 || whereShortCut(&sWLB)==0 ){ |
︙ | ︙ | |||
5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 | assert( pIx->pSchema==pTab->pSchema ); assert( iIndexCur>=0 ); if( op ){ sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIx); if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0 && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED ){ sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */ } VdbeComment((v, "%s", pIx->zName)); #ifdef SQLITE_ENABLE_COLUMN_USED_MASK | > | 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 | assert( pIx->pSchema==pTab->pSchema ); assert( iIndexCur>=0 ); if( op ){ sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIx); if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0 && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 && (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0 && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED ){ sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */ } VdbeComment((v, "%s", pIx->zName)); #ifdef SQLITE_ENABLE_COLUMN_USED_MASK |
︙ | ︙ | |||
5154 5155 5156 5157 5158 5159 5160 | int addrSeek = 0; Index *pIdx; int n; if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED && i==pWInfo->nLevel-1 /* Ticket [ef9318757b152e3] 2017-10-21 */ && (pLoop->wsFlags & WHERE_INDEXED)!=0 && (pIdx = pLoop->u.btree.pIndex)->hasStat1 | | | 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 | int addrSeek = 0; Index *pIdx; int n; if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED && i==pWInfo->nLevel-1 /* Ticket [ef9318757b152e3] 2017-10-21 */ && (pLoop->wsFlags & WHERE_INDEXED)!=0 && (pIdx = pLoop->u.btree.pIndex)->hasStat1 && (n = pLoop->u.btree.nDistinctCol)>0 && pIdx->aiRowLogEst[n]>=36 ){ int r1 = pParse->nMem+1; int j, op; for(j=0; j<n; j++){ sqlite3VdbeAddOp3(v, OP_Column, pLevel->iIdxCur, j, r1+j); } |
︙ | ︙ | |||
5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 | sqlite3VdbeResolveLabel(v, pLevel->addrCont); sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); sqlite3VdbeChangeP5(v, pLevel->p5); VdbeCoverage(v); VdbeCoverageIf(v, pLevel->op==OP_Next); VdbeCoverageIf(v, pLevel->op==OP_Prev); VdbeCoverageIf(v, pLevel->op==OP_VNext); #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); #endif }else{ sqlite3VdbeResolveLabel(v, pLevel->addrCont); } if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ | > > > > > | 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 | sqlite3VdbeResolveLabel(v, pLevel->addrCont); sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); sqlite3VdbeChangeP5(v, pLevel->p5); VdbeCoverage(v); VdbeCoverageIf(v, pLevel->op==OP_Next); VdbeCoverageIf(v, pLevel->op==OP_Prev); VdbeCoverageIf(v, pLevel->op==OP_VNext); if( pLevel->regBignull ){ sqlite3VdbeResolveLabel(v, pLevel->addrBignull); sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1); VdbeCoverage(v); } #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); #endif }else{ sqlite3VdbeResolveLabel(v, pLevel->addrCont); } if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ |
︙ | ︙ |
Changes to src/whereInt.h.
︙ | ︙ | |||
67 68 69 70 71 72 73 74 75 76 77 78 79 | int iIdxCur; /* The VDBE cursor used to access pIdx */ int addrBrk; /* Jump here to break out of the loop */ int addrNxt; /* Jump here to start the next IN combination */ int addrSkip; /* Jump here for next iteration of skip-scan */ int addrCont; /* Jump here to continue with the next loop cycle */ int addrFirst; /* First instruction of interior of the loop */ int addrBody; /* Beginning of the body of this loop */ #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ int addrLikeRep; /* LIKE range processing address */ #endif u8 iFrom; /* Which entry in the FROM clause */ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ | > > | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | int iIdxCur; /* The VDBE cursor used to access pIdx */ int addrBrk; /* Jump here to break out of the loop */ int addrNxt; /* Jump here to start the next IN combination */ int addrSkip; /* Jump here for next iteration of skip-scan */ int addrCont; /* Jump here to continue with the next loop cycle */ int addrFirst; /* First instruction of interior of the loop */ int addrBody; /* Beginning of the body of this loop */ int regBignull; /* big-null flag reg. True if a NULL-scan is needed */ int addrBignull; /* Jump here for next part of big-null scan */ #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ int addrLikeRep; /* LIKE range processing address */ #endif u8 iFrom; /* Which entry in the FROM clause */ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ int p1, p2; /* Operands of the opcode used to end the loop */ union { /* Information that depends on pWLoop->wsFlags */ struct { int nIn; /* Number of entries in aInLoop[] */ struct InLoop { int iCur; /* The VDBE cursor used by this IN operator */ int addrInTop; /* Top of the IN loop */ int iBase; /* Base register of multi-key index record */ |
︙ | ︙ | |||
124 125 126 127 128 129 130 | LogEst rRun; /* Cost of running each loop */ LogEst nOut; /* Estimated number of output rows */ union { struct { /* Information for internal btree tables */ u16 nEq; /* Number of equality constraints */ u16 nBtm; /* Size of BTM vector */ u16 nTop; /* Size of TOP vector */ | | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | LogEst rRun; /* Cost of running each loop */ LogEst nOut; /* Estimated number of output rows */ union { struct { /* Information for internal btree tables */ u16 nEq; /* Number of equality constraints */ u16 nBtm; /* Size of BTM vector */ u16 nTop; /* Size of TOP vector */ u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ Index *pIndex; /* Index used, or NULL */ } btree; struct { /* Information for virtual tables */ int idxNum; /* Index number */ u8 needFree; /* True if sqlite3_free(idxStr) is needed */ i8 isOrdered; /* True if satisfies ORDER BY */ u16 omitMask; /* Terms that may be omitted */ |
︙ | ︙ | |||
275 276 277 278 279 280 281 | #define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(db, pExpr) */ #define TERM_VIRTUAL 0x02 /* Added by the optimizer. Do not code */ #define TERM_CODED 0x04 /* This term is already coded */ #define TERM_COPIED 0x08 /* Has a child */ #define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ #define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ #define TERM_OR_OK 0x40 /* Used during OR-clause processing */ | | | > | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | #define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(db, pExpr) */ #define TERM_VIRTUAL 0x02 /* Added by the optimizer. Do not code */ #define TERM_CODED 0x04 /* This term is already coded */ #define TERM_COPIED 0x08 /* Has a child */ #define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ #define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ #define TERM_OR_OK 0x40 /* Used during OR-clause processing */ #ifdef SQLITE_ENABLE_STAT4 # define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ #else # define TERM_VNULL 0x00 /* Disabled if not using stat4 */ #endif #define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */ #define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */ #define TERM_LIKE 0x400 /* The original LIKE operator */ #define TERM_IS 0x800 /* Term.pExpr is an IS operator */ #define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */ #define TERM_NOPARTIDX 0x2000 /* Not for use to enable a partial index */ /* ** An instance of the WhereScan object is used as an iterator for locating ** terms in the WHERE clause that are useful to the query planner. */ struct WhereScan { WhereClause *pOrigWC; /* Original, innermost WhereClause */ |
︙ | ︙ | |||
395 396 397 398 399 400 401 | */ struct WhereLoopBuilder { WhereInfo *pWInfo; /* Information about this WHERE */ WhereClause *pWC; /* WHERE clause terms */ ExprList *pOrderBy; /* ORDER BY clause */ WhereLoop *pNew; /* Template WhereLoop */ WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ | | | 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 | */ struct WhereLoopBuilder { WhereInfo *pWInfo; /* Information about this WHERE */ WhereClause *pWC; /* WHERE clause terms */ ExprList *pOrderBy; /* ORDER BY clause */ WhereLoop *pNew; /* Template WhereLoop */ WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ #ifdef SQLITE_ENABLE_STAT4 UnpackedRecord *pRec; /* Probe for stat4 (if required) */ int nRecValid; /* Number of valid fields currently in pRec */ #endif unsigned int bldFlags; /* SQLITE_BLDF_* flags */ unsigned int iPlanLimit; /* Search limiter */ }; |
︙ | ︙ | |||
582 583 584 585 586 587 588 589 590 | #define WHERE_ONEROW 0x00001000 /* Selects no more than one row */ #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ #endif /* !defined(SQLITE_WHEREINT_H) */ | > | 585 586 587 588 589 590 591 592 593 594 | #define WHERE_ONEROW 0x00001000 /* Selects no more than one row */ #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */ #endif /* !defined(SQLITE_WHEREINT_H) */ |
Changes to src/wherecode.c.
︙ | ︙ | |||
314 315 316 317 318 319 320 | } } /* ** Code an OP_Affinity opcode to apply the column affinity string zAff ** to the n registers starting at base. ** | | | | | | > | | | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | } } /* ** Code an OP_Affinity opcode to apply the column affinity string zAff ** to the n registers starting at base. ** ** As an optimization, SQLITE_AFF_BLOB and SQLITE_AFF_NONE entries (which ** are no-ops) at the beginning and end of zAff are ignored. If all entries ** in zAff are SQLITE_AFF_BLOB or SQLITE_AFF_NONE, then no code gets generated. ** ** This routine makes its own copy of zAff so that the caller is free ** to modify zAff after this routine returns. */ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ Vdbe *v = pParse->pVdbe; if( zAff==0 ){ assert( pParse->db->mallocFailed ); return; } assert( v!=0 ); /* Adjust base and n to skip over SQLITE_AFF_BLOB and SQLITE_AFF_NONE ** entries at the beginning and end of the affinity string. */ assert( SQLITE_AFF_NONE<SQLITE_AFF_BLOB ); while( n>0 && zAff[0]<=SQLITE_AFF_BLOB ){ n--; base++; zAff++; } while( n>1 && zAff[n-1]<=SQLITE_AFF_BLOB ){ n--; } /* Code the OP_Affinity opcode if there is anything left to do. */ if( n>0 ){ sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n); } |
︙ | ︙ | |||
1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 | ** ** If pExpr matches, then transform it into a reference to the index column ** that contains the value of pExpr. */ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ IdxExprTrans *pX = p->u.pIdxTrans; if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ pExpr->op = TK_COLUMN; pExpr->iTable = pX->iIdxCur; pExpr->iColumn = pX->iIdxCol; pExpr->y.pTab = 0; return WRC_Prune; }else{ return WRC_Continue; | > | 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 | ** ** If pExpr matches, then transform it into a reference to the index column ** that contains the value of pExpr. */ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ IdxExprTrans *pX = p->u.pIdxTrans; if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ pExpr->affExpr = sqlite3ExprAffinity(pExpr); pExpr->op = TK_COLUMN; pExpr->iTable = pX->iIdxCur; pExpr->iColumn = pX->iIdxCol; pExpr->y.pTab = 0; return WRC_Prune; }else{ return WRC_Continue; |
︙ | ︙ | |||
1544 1545 1546 1547 1548 1549 1550 | int nExtraReg = 0; /* Number of extra registers needed */ int op; /* Instruction opcode */ char *zStartAff; /* Affinity for start of range constraint */ char *zEndAff = 0; /* Affinity for end of range constraint */ u8 bSeekPastNull = 0; /* True to seek past initial nulls */ u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ int omitTable; /* True if we use the index only */ | | < < < < < < < < < < < < < < < < < < < < | 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 | int nExtraReg = 0; /* Number of extra registers needed */ int op; /* Instruction opcode */ char *zStartAff; /* Affinity for start of range constraint */ char *zEndAff = 0; /* Affinity for end of range constraint */ u8 bSeekPastNull = 0; /* True to seek past initial nulls */ u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ int omitTable; /* True if we use the index only */ int regBignull = 0; /* big-null flag register */ pIdx = pLoop->u.btree.pIndex; iIdxCur = pLevel->iIdxCur; assert( nEq>=pLoop->nSkip ); /* Find any inequality constraint terms for the start and end ** of the range. */ j = nEq; if( pLoop->wsFlags & WHERE_BTM_LIMIT ){ pRangeStart = pLoop->aLTerm[j++]; nExtraReg = MAX(nExtraReg, pLoop->u.btree.nBtm); |
︙ | ︙ | |||
1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 | j = pIdx->aiColumn[nEq]; if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){ bSeekPastNull = 1; } } } assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 ); /* If we are doing a reverse order scan on an ascending index, or ** a forward order scan on a descending index, interchange the ** start and end terms (pRangeStart and pRangeEnd). */ if( (nEq<pIdx->nKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) || (bRev && pIdx->nKeyCol==nEq) | > > > > > > > > > > > > > > > > > > > | 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 | j = pIdx->aiColumn[nEq]; if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){ bSeekPastNull = 1; } } } assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 ); /* If the WHERE_BIGNULL_SORT flag is set, then index column nEq uses ** a non-default "big-null" sort (either ASC NULLS LAST or DESC NULLS ** FIRST). In both cases separate ordered scans are made of those ** index entries for which the column is null and for those for which ** it is not. For an ASC sort, the non-NULL entries are scanned first. ** For DESC, NULL entries are scanned first. */ if( (pLoop->wsFlags & (WHERE_TOP_LIMIT|WHERE_BTM_LIMIT))==0 && (pLoop->wsFlags & WHERE_BIGNULL_SORT)!=0 ){ assert( bSeekPastNull==0 && nExtraReg==0 && nBtm==0 && nTop==0 ); assert( pRangeEnd==0 && pRangeStart==0 ); assert( pLoop->nSkip==0 ); nExtraReg = 1; bSeekPastNull = 1; pLevel->regBignull = regBignull = ++pParse->nMem; pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse); } /* If we are doing a reverse order scan on an ascending index, or ** a forward order scan on a descending index, interchange the ** start and end terms (pRangeStart and pRangeEnd). */ if( (nEq<pIdx->nKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) || (bRev && pIdx->nKeyCol==nEq) |
︙ | ︙ | |||
1632 1633 1634 1635 1636 1637 1638 | */ codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd); regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); if( zStartAff && nTop ){ zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]); } | | | 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 | */ codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd); regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); if( zStartAff && nTop ){ zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]); } addrNxt = (regBignull ? pLevel->addrBignull : pLevel->addrNxt); testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 ); testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 ); testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 ); startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE); endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE); |
︙ | ︙ | |||
1666 1667 1668 1669 1670 1671 1672 1673 1674 | if( sqlite3ExprIsVector(pRight)==0 ){ disableTerm(pLevel, pRangeStart); }else{ startEq = 1; } bSeekPastNull = 0; }else if( bSeekPastNull ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); nConstraint++; | > > < > > > > > > > > > > > > > > > > > > > > > > > > > | 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 | if( sqlite3ExprIsVector(pRight)==0 ){ disableTerm(pLevel, pRangeStart); }else{ startEq = 1; } bSeekPastNull = 0; }else if( bSeekPastNull ){ startEq = 0; sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); start_constraints = 1; nConstraint++; }else if( regBignull ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); start_constraints = 1; nConstraint++; } codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff); if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){ /* The skip-scan logic inside the call to codeAllEqualityConstraints() ** above has already left the cursor sitting on the correct row, ** so no further seeking is needed */ }else{ if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); } if( regBignull ){ sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull); VdbeComment((v, "NULL-scan pass ctr")); } op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); VdbeCoverage(v); VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT ); VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); assert( bSeekPastNull==0 || bStopAtNull==0 ); if( regBignull ){ assert( bSeekPastNull==1 || bStopAtNull==1 ); assert( bSeekPastNull==!bStopAtNull ); assert( bStopAtNull==startEq ); sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); op = aStartOp[(nConstraint>1)*4 + 2 + bRev]; sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint-startEq); VdbeCoverage(v); VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); assert( op==OP_Rewind || op==OP_Last || op==OP_SeekGE || op==OP_SeekLE); } } /* Load the value for the inequality constraint at the end of the ** range (if any). */ nConstraint = nEq; if( pRangeEnd ){ |
︙ | ︙ | |||
1721 1722 1723 1724 1725 1726 1727 | if( sqlite3ExprIsVector(pRight)==0 ){ disableTerm(pLevel, pRangeEnd); }else{ endEq = 1; } }else if( bStopAtNull ){ | > | | > > > > > > > > > > > > > > > > > > > > > > > > | 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 | if( sqlite3ExprIsVector(pRight)==0 ){ disableTerm(pLevel, pRangeEnd); }else{ endEq = 1; } }else if( bStopAtNull ){ if( regBignull==0 ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); endEq = 0; } nConstraint++; } sqlite3DbFree(db, zStartAff); sqlite3DbFree(db, zEndAff); /* Top of the loop body */ pLevel->p2 = sqlite3VdbeCurrentAddr(v); /* Check if the index cursor is past the end of the range. */ if( nConstraint ){ if( regBignull ){ /* Except, skip the end-of-range check while doing the NULL-scan */ sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+3); VdbeComment((v, "If NULL-scan 2nd pass")); VdbeCoverage(v); } op = aEndOp[bRev*2 + endEq]; sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } if( regBignull ){ /* During a NULL-scan, check to see if we have reached the end of ** the NULLs */ assert( bSeekPastNull==!bStopAtNull ); assert( bSeekPastNull+bStopAtNull==1 ); assert( nConstraint+bSeekPastNull>0 ); sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+2); VdbeComment((v, "If NULL-scan 1st pass")); VdbeCoverage(v); op = aEndOp[bRev*2 + bSeekPastNull]; sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint+bSeekPastNull); testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ |
︙ | ︙ |
Changes to src/whereexpr.c.
︙ | ︙ | |||
80 81 82 83 84 85 86 | } pTerm = &pWC->a[idx = pWC->nTerm++]; if( p && ExprHasProperty(p, EP_Unlikely) ){ pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; }else{ pTerm->truthProb = 1; } | | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | } pTerm = &pWC->a[idx = pWC->nTerm++]; if( p && ExprHasProperty(p, EP_Unlikely) ){ pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; }else{ pTerm->truthProb = 1; } pTerm->pExpr = sqlite3ExprSkipCollateAndLikely(p); pTerm->wtFlags = wtFlags; pTerm->pWC = pWC; pTerm->iParent = -1; memset(&pTerm->eOperator, 0, sizeof(WhereTerm) - offsetof(WhereTerm,eOperator)); return idx; } |
︙ | ︙ | |||
113 114 115 116 117 118 119 120 | ** If left/right precedence rules come into play when determining the ** collating sequence, then COLLATE operators are adjusted to ensure ** that the collating sequence does not change. For example: ** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on ** the left hand side of a comparison overrides any collation sequence ** attached to the right. For the same reason the EP_Collate flag ** is not commuted. */ | > > > > > | > > > > | 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 | ** If left/right precedence rules come into play when determining the ** collating sequence, then COLLATE operators are adjusted to ensure ** that the collating sequence does not change. For example: ** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on ** the left hand side of a comparison overrides any collation sequence ** attached to the right. For the same reason the EP_Collate flag ** is not commuted. ** ** The return value is extra flags that are added to the WhereTerm object ** after it is commuted. The only extra flag ever added is TERM_NOPARTIDX ** which prevents the term from being used to enable a partial index if ** COLLATE changes have been made. */ static u16 exprCommute(Parse *pParse, Expr *pExpr){ u16 expRight = (pExpr->pRight->flags & EP_Collate); u16 expLeft = (pExpr->pLeft->flags & EP_Collate); u16 wtFlags = 0; assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN ); if( expRight==expLeft ){ /* Either X and Y both have COLLATE operator or neither do */ if( expRight ){ /* Both X and Y have COLLATE operators. Make sure X is always ** used by clearing the EP_Collate flag from Y. */ pExpr->pRight->flags &= ~EP_Collate; wtFlags |= TERM_NOPARTIDX; }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){ /* Neither X nor Y have COLLATE operators, but X has a non-default ** collating sequence. So add the EP_Collate marker on X to cause ** it to be searched first. */ pExpr->pLeft->flags |= EP_Collate; wtFlags |= TERM_NOPARTIDX; } } SWAP(Expr*,pExpr->pRight,pExpr->pLeft); if( pExpr->op>=TK_GT ){ assert( TK_LT==TK_GT+2 ); assert( TK_GE==TK_LE+2 ); assert( TK_GT>TK_EQ ); assert( TK_GT<TK_LE ); assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE ); pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT; } return wtFlags; } /* ** Translate from TK_xx operator to WO_xx bitmask. */ static u16 operatorMask(int op){ u16 c; |
︙ | ︙ | |||
1136 1137 1138 1139 1140 1141 1142 | pTerm->eOperator |= WO_EQUIV; eExtraOp = WO_EQUIV; } }else{ pDup = pExpr; pNew = pTerm; } | | | 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 | pTerm->eOperator |= WO_EQUIV; eExtraOp = WO_EQUIV; } }else{ pDup = pExpr; pNew = pTerm; } pNew->wtFlags |= exprCommute(pParse, pDup); pNew->leftCursor = aiCurCol[0]; pNew->u.leftColumn = aiCurCol[1]; testcase( (prereqLeft | extraRight) != prereqLeft ); pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll; pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; } |
︙ | ︙ | |||
1377 1378 1379 1380 1381 1382 1383 | idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL); pWC->a[idxNew].iField = i+1; exprAnalyze(pSrc, pWC, idxNew); markTermAsChild(pWC, idxNew, idxTerm); } } | | | | | 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 | idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL); pWC->a[idxNew].iField = i+1; exprAnalyze(pSrc, pWC, idxNew); markTermAsChild(pWC, idxNew, idxTerm); } } #ifdef SQLITE_ENABLE_STAT4 /* When sqlite_stat4 histogram data is available an operator of the ** form "x IS NOT NULL" can sometimes be evaluated more efficiently ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a ** virtual term of that form. ** ** Note that the virtual term must be tagged with TERM_VNULL. */ if( pExpr->op==TK_NOTNULL && pExpr->pLeft->op==TK_COLUMN && pExpr->pLeft->iColumn>=0 && !ExprHasProperty(pExpr, EP_FromJoin) && OptimizationEnabled(db, SQLITE_Stat4) ){ Expr *pNewExpr; Expr *pLeft = pExpr->pLeft; int idxNew; WhereTerm *pNewTerm; pNewExpr = sqlite3PExpr(pParse, TK_GT, |
︙ | ︙ | |||
1414 1415 1416 1417 1418 1419 1420 | pNewTerm->eOperator = WO_GT; markTermAsChild(pWC, idxNew, idxTerm); pTerm = &pWC->a[idxTerm]; pTerm->wtFlags |= TERM_COPIED; pNewTerm->prereqAll = pTerm->prereqAll; } } | | | 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 | pNewTerm->eOperator = WO_GT; markTermAsChild(pWC, idxNew, idxTerm); pTerm = &pWC->a[idxTerm]; pTerm->wtFlags |= TERM_COPIED; pNewTerm->prereqAll = pTerm->prereqAll; } } #endif /* SQLITE_ENABLE_STAT4 */ /* Prevent ON clause terms of a LEFT JOIN from being used to drive ** an index for tables to the left of the join. */ testcase( pTerm!=&pWC->a[idxTerm] ); pTerm = &pWC->a[idxTerm]; pTerm->prereqRight |= extraRight; |
︙ | ︙ | |||
1447 1448 1449 1450 1451 1452 1453 | ** does is make slot[] entries point to substructure within pExpr. ** ** In the previous sentence and in the diagram, "slot[]" refers to ** the WhereClause.a[] array. The slot[] array grows as needed to contain ** all terms of the WHERE clause. */ void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ | | | 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 | ** does is make slot[] entries point to substructure within pExpr. ** ** In the previous sentence and in the diagram, "slot[]" refers to ** the WhereClause.a[] array. The slot[] array grows as needed to contain ** all terms of the WHERE clause. */ void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pExpr); pWC->op = op; if( pE2==0 ) return; if( pE2->op!=op ){ whereClauseInsert(pWC, pExpr, 0); }else{ sqlite3WhereSplit(pWC, pE2->pLeft, op); sqlite3WhereSplit(pWC, pE2->pRight, op); |
︙ | ︙ |
Changes to src/window.c.
︙ | ︙ | |||
744 745 746 747 748 749 750 751 752 753 754 755 756 757 | ** 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 ){ | > > | 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 | ** Callback function used by selectWindowRewriteEList(). If necessary, ** this function appends to the output expression-list and updates ** expression (*ppExpr) in place. */ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ struct WindowRewrite *p = pWalker->u.pRewrite; Parse *pParse = pWalker->pParse; assert( p!=0 ); assert( p->pWin!=0 ); /* If this function is being called from within a scalar sub-select ** that used by the SELECT statement being processed, only process ** TK_COLUMN expressions that refer to it (the outer SELECT). Do ** not process aggregates or window functions at all, as they belong ** to the scalar sub-select. */ if( p->pSubSelect ){ |
︙ | ︙ | |||
843 844 845 846 847 848 849 850 851 852 853 854 855 856 | ExprList *pEList, /* Rewrite expressions in this list */ Table *pTab, 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; sRewrite.pTab = pTab; | > | 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 | ExprList *pEList, /* Rewrite expressions in this list */ Table *pTab, ExprList **ppSub /* IN/OUT: Sub-select expression-list */ ){ Walker sWalker; WindowRewrite sRewrite; assert( pWin!=0 ); memset(&sWalker, 0, sizeof(Walker)); memset(&sRewrite, 0, sizeof(WindowRewrite)); sRewrite.pSub = *ppSub; sRewrite.pWin = pWin; sRewrite.pSrc = pSrc; sRewrite.pTab = pTab; |
︙ | ︙ | |||
881 882 883 884 885 886 887 | for(i=0; i<pAppend->nExpr; i++){ Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); if( bIntToNull && pDup && pDup->op==TK_INTEGER ){ pDup->op = TK_NULL; pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); } pList = sqlite3ExprListAppend(pParse, pList, pDup); | | | 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 | for(i=0; i<pAppend->nExpr; i++){ Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); if( bIntToNull && pDup && pDup->op==TK_INTEGER ){ pDup->op = TK_NULL; pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); } pList = sqlite3ExprListAppend(pParse, pList, pDup); if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags; } } return pList; } /* ** If the SELECT statement passed as the second argument does not invoke |
︙ | ︙ | |||
927 928 929 930 931 932 933 | p->selFlags &= ~SF_Aggregate; /* 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, 1); | | > > > | 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 | p->selFlags &= ~SF_Aggregate; /* 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, 1); if( pSort && p->pOrderBy && p->pOrderBy->nExpr<=pSort->nExpr ){ int nSave = pSort->nExpr; pSort->nExpr = p->pOrderBy->nExpr; if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){ sqlite3ExprListDelete(db, p->pOrderBy); p->pOrderBy = 0; } pSort->nExpr = nSave; } /* Assign a cursor number for the ephemeral table used to buffer rows. ** The OpenEphemeral instruction is coded later, after it is known how ** many columns the table will have. */ pMWin->iEphCsr = pParse->nTab++; pParse->nTab += 3; |
︙ | ︙ | |||
955 956 957 958 959 960 961 | pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0); /* 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){ | > > > | > > > | > | 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 | pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0); /* Append the arguments passed to each window function to the ** sub-select expression list. Also allocate two registers for each ** window function - one for the accumulator, another for interim ** results. */ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ ExprList *pArgs = pWin->pOwner->x.pList; if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){ selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); pWin->bExprArgs = 1; }else{ pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); pSublist = exprListAppendList(pParse, pSublist, pArgs, 0); } 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); |
︙ | ︙ | |||
987 988 989 990 991 992 993 | ); p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( p->pSrc ){ Table *pTab2; p->pSrc->a[0].pSelect = pSub; sqlite3SrcListAssignCursors(pParse, p->pSrc); pSub->selFlags |= SF_Expanded; | | | 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 | ); p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( p->pSrc ){ Table *pTab2; p->pSrc->a[0].pSelect = pSub; sqlite3SrcListAssignCursors(pParse, p->pSrc); pSub->selFlags |= SF_Expanded; pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); if( pTab2==0 ){ rc = SQLITE_NOMEM; }else{ memcpy(pTab, pTab2, sizeof(Table)); pTab->tabFlags |= TF_Ephemeral; p->pSrc->a[0].pTab = pTab; pTab = pTab2; |
︙ | ︙ | |||
1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 | } if( db->mallocFailed ) rc = SQLITE_NOMEM; sqlite3DbFree(db, pTab); } 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->zBase); | > > > > > > > > > > > > > | 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 | } if( db->mallocFailed ) rc = SQLITE_NOMEM; sqlite3DbFree(db, pTab); } return rc; } /* ** Unlink the Window object from the Select to which it is attached, ** if it is attached. */ void sqlite3WindowUnlinkFromSelect(Window *p){ if( p->ppThis ){ *p->ppThis = p->pNextWin; if( p->pNextWin ) p->pNextWin->ppThis = p->ppThis; p->ppThis = 0; } } /* ** Free the Window object passed as the second argument. */ void sqlite3WindowDelete(sqlite3 *db, Window *p){ if( p ){ sqlite3WindowUnlinkFromSelect(p); sqlite3ExprDelete(db, p->pFilter); sqlite3ExprListDelete(db, p->pPartition); sqlite3ExprListDelete(db, p->pOrderBy); sqlite3ExprDelete(db, p->pEnd); sqlite3ExprDelete(db, p->pStart); sqlite3DbFree(db, p->zName); sqlite3DbFree(db, p->zBase); |
︙ | ︙ | |||
1192 1193 1194 1195 1196 1197 1198 | /* ** Attach window object pWin to expression p. */ void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ if( p ){ assert( p->op==TK_FUNCTION ); | < < < | | | | | | | < > > > > > > > > > > > > > > > > > > > > | > > > | 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 | /* ** Attach window object pWin to expression p. */ void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ if( p ){ assert( p->op==TK_FUNCTION ); assert( pWin ); p->y.pWin = pWin; ExprSetProperty(p, EP_WinFunc); pWin->pOwner = p; if( (p->flags & EP_Distinct) && pWin->eFrmType!=TK_FILTER ){ sqlite3ErrorMsg(pParse, "DISTINCT is not supported for window functions" ); } }else{ sqlite3WindowDelete(pParse->db, pWin); } } /* ** Possibly link window pWin into the list at pSel->pWin (window functions ** to be processed as part of SELECT statement pSel). The window is linked ** in if either (a) there are no other windows already linked to this ** SELECT, or (b) the windows already linked use a compatible window frame. */ void sqlite3WindowLink(Select *pSel, Window *pWin){ if( 0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0) ){ pWin->pNextWin = pSel->pWin; if( pSel->pWin ){ pSel->pWin->ppThis = &pWin->pNextWin; } pSel->pWin = pWin; pWin->ppThis = &pSel->pWin; } } /* ** Return 0 if the two window objects are identical, or non-zero otherwise. ** Identical window objects can be processed in a single scan. */ int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2, int bFilter){ if( p1->eFrmType!=p2->eFrmType ) return 1; if( p1->eStart!=p2->eStart ) return 1; if( p1->eEnd!=p2->eEnd ) return 1; if( p1->eExclude!=p2->eExclude ) return 1; if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1; if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1; if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1; if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1; if( bFilter ){ if( sqlite3ExprCompare(pParse, p1->pFilter, p2->pFilter, -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 |
︙ | ︙ | |||
1273 1274 1275 1276 1277 1278 1279 | */ 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' ){ | | | | 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 | */ ExprList *pList = pWin->pOwner->x.pList; KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0); pWin->csrApp = pParse->nTab++; pWin->regApp = pParse->nMem+1; pParse->nMem += 3; if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){ assert( pKeyInfo->aSortFlags[0]==0 ); pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC; } 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 |
︙ | ︙ | |||
1390 1391 1392 1393 1394 1395 1396 | int reg /* Array of registers */ ){ Vdbe *v = sqlite3GetVdbe(pParse); Window *pWin; for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ FuncDef *pFunc = pWin->pFunc; int regArg; | | > > | 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 | int reg /* Array of registers */ ){ Vdbe *v = sqlite3GetVdbe(pParse); Window *pWin; for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ FuncDef *pFunc = pWin->pFunc; int regArg; int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin); int i; assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); for(i=0; i<nArg; i++){ if( i!=1 || pFunc->zName!=nth_valueName ){ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i); }else{ sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i); } |
︙ | ︙ | |||
1430 1431 1432 1433 1434 1435 1436 | ); assert( bInverse==0 || bInverse==1 ); sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); }else if( pFunc->xSFunc!=noopStepFunc ){ int addrIf = 0; if( pWin->pFilter ){ int regTmp; | | | > > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < | > | | | 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 | ); assert( bInverse==0 || bInverse==1 ); sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); }else if( pFunc->xSFunc!=noopStepFunc ){ int addrIf = 0; if( pWin->pFilter ){ int regTmp; assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); regTmp = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); VdbeCoverage(v); sqlite3ReleaseTempReg(pParse, regTmp); } if( pWin->bExprArgs ){ int iStart = sqlite3VdbeCurrentAddr(v); VdbeOp *pOp, *pEnd; nArg = pWin->pOwner->x.pList->nExpr; regArg = sqlite3GetTempRange(pParse, nArg); sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0); pEnd = sqlite3VdbeGetOp(v, -1); for(pOp=sqlite3VdbeGetOp(v, iStart); pOp<=pEnd; pOp++){ if( pOp->opcode==OP_Column && pOp->p1==pWin->iEphCsr ){ pOp->p1 = csr; } } } if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ CollSeq *pColl; assert( nArg>0 ); pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); } sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, bInverse, regArg, pWin->regAccum); sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); if( pWin->bExprArgs ){ sqlite3ReleaseTempRange(pParse, regArg, nArg); } if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } } } typedef struct WindowCodeArg WindowCodeArg; typedef struct WindowCsrAndReg WindowCsrAndReg; /* ** See comments above struct WindowCodeArg. */ struct WindowCsrAndReg { int csr; /* Cursor number */ int reg; /* First in array of peer values */ }; /* ** A single instance of this structure is allocated on the stack by ** sqlite3WindowCodeStep() and a pointer to it passed to the various helper ** routines. This is to reduce the number of arguments required by each ** helper function. ** ** regArg: ** Each window function requires an accumulator register (just as an ** ordinary aggregate function does). This variable is set to the first ** in an array of accumulator registers - one for each window function ** in the WindowCodeArg.pMWin list. ** ** eDelete: ** The window functions implementation sometimes caches the input rows ** that it processes in a temporary table. If it is not zero, this ** variable indicates when rows may be removed from the temp table (in ** order to reduce memory requirements - it would always be safe just ** to leave them there). Possible values for eDelete are: ** ** WINDOW_RETURN_ROW: ** An input row can be discarded after it is returned to the caller. ** ** WINDOW_AGGINVERSE: ** An input row can be discarded after the window functions xInverse() ** callbacks have been invoked in it. ** ** WINDOW_AGGSTEP: ** An input row can be discarded after the window functions xStep() ** callbacks have been invoked in it. ** ** start,current,end ** Consider a window-frame similar to the following: ** ** (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING) ** ** The windows functions implmentation caches the input rows in a temp ** table, sorted by "a, b" (it actually populates the cache lazily, and ** aggressively removes rows once they are no longer required, but that's ** a mere detail). It keeps three cursors open on the temp table. One ** (current) that points to the next row to return to the query engine ** once its window function values have been calculated. Another (end) ** points to the next row to call the xStep() method of each window function ** on (so that it is 2 groups ahead of current). And a third (start) that ** points to the next row to call the xInverse() method of each window ** function on. ** ** Each cursor (start, current and end) consists of a VDBE cursor ** (WindowCsrAndReg.csr) and an array of registers (starting at ** WindowCodeArg.reg) that always contains a copy of the peer values ** read from the corresponding cursor. ** ** Depending on the window-frame in question, all three cursors may not ** be required. In this case both WindowCodeArg.csr and reg are set to ** 0. */ struct WindowCodeArg { Parse *pParse; /* Parse context */ Window *pMWin; /* First in list of functions being processed */ Vdbe *pVdbe; /* VDBE object */ int addrGosub; /* OP_Gosub to this address to return one row */ int regGosub; /* Register used with OP_Gosub(addrGosub) */ int regArg; /* First in array of accumulator registers */ int eDelete; /* See above */ WindowCsrAndReg start; WindowCsrAndReg current; WindowCsrAndReg end; }; /* |
︙ | ︙ | |||
1563 1564 1565 1566 1567 1568 1569 | int regRowid = 0; /* AggStep rowid value */ int regPeer = 0; /* AggStep peer values */ int nPeer; int lblNext; int lblBrk; int addrNext; | | > > | 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 | int regRowid = 0; /* AggStep rowid value */ int regPeer = 0; /* AggStep peer values */ int nPeer; int lblNext; int lblBrk; int addrNext; int csr; assert( pMWin!=0 ); csr = pMWin->csrApp; nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0); lblNext = sqlite3VdbeMakeLabel(pParse); lblBrk = sqlite3VdbeMakeLabel(pParse); regCRowid = sqlite3GetTempReg(pParse); regRowid = sqlite3GetTempReg(pParse); |
︙ | ︙ | |||
1808 1809 1810 1811 1812 1813 1814 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); } } /* ** This function is called as part of generating VM programs for RANGE ** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for | | > > > > > > > > > > > > | | | | | | | | > | | > | | < < | | > | > > > | > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < > > | 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); } } /* ** This function is called as part of generating VM programs for RANGE ** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for ** the ORDER BY term in the window, and that argument op is OP_Ge, it generates ** code equivalent to: ** ** if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl; ** ** The value of parameter op may also be OP_Gt or OP_Le. In these cases the ** operator in the above pseudo-code is replaced with ">" or "<=", respectively. ** ** If the sort-order for the ORDER BY term in the window is DESC, then the ** comparison is reversed. Instead of adding regVal to csr1.peerVal, it is ** subtracted. And the comparison operator is inverted to - ">=" becomes "<=", ** ">" becomes "<", and so on. So, with DESC sort order, if the argument op ** is OP_Ge, the generated code is equivalent to: ** ** if( csr1.peerVal - regVal <= csr2.peerVal ) goto lbl; ** ** A special type of arithmetic is used such that if csr1.peerVal is not ** a numeric type (real or integer), then the result of the addition addition ** or subtraction is a a copy of csr1.peerVal. */ static void windowCodeRangeTest( WindowCodeArg *p, int op, /* OP_Ge, OP_Gt, or OP_Le */ int csr1, /* Cursor number for cursor 1 */ int regVal, /* Register containing non-negative number */ int csr2, /* Cursor number for cursor 2 */ int lbl /* Jump destination if condition is true */ ){ Parse *pParse = p->pParse; Vdbe *v = sqlite3GetVdbe(pParse); ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for window */ int reg1 = sqlite3GetTempReg(pParse); /* Reg. for csr1.peerVal+regVal */ int reg2 = sqlite3GetTempReg(pParse); /* Reg. for csr2.peerVal */ int regString = ++pParse->nMem; /* Reg. for constant value '' */ int arith = OP_Add; /* OP_Add or OP_Subtract */ int addrGe; /* Jump destination */ assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); assert( pOrderBy && pOrderBy->nExpr==1 ); if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){ switch( op ){ case OP_Ge: op = OP_Le; break; case OP_Gt: op = OP_Lt; break; default: assert( op==OP_Le ); op = OP_Ge; break; } arith = OP_Subtract; } /* Read the peer-value from each cursor into a register */ windowReadPeerValues(p, csr1, reg1); windowReadPeerValues(p, csr2, reg2); VdbeModuleComment((v, "CodeRangeTest: if( R%d %s R%d %s R%d ) goto lbl", reg1, (arith==OP_Add ? "+" : "-"), regVal, ((op==OP_Ge) ? ">=" : (op==OP_Le) ? "<=" : (op==OP_Gt) ? ">" : "<"), reg2 )); /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1). ** This block adds (or subtracts for DESC) the numeric value in regVal ** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob), ** then leave reg1 as it is. In pseudo-code, this is implemented as: ** ** if( reg1>='' ) goto addrGe; ** reg1 = reg1 +/- regVal ** addrGe: ** ** Since all strings and blobs are greater-than-or-equal-to an empty string, ** the add/subtract is skipped for these, as required. If reg1 is a NULL, ** then the arithmetic is performed, but since adding or subtracting from ** NULL is always NULL anyway, this case is handled as required too. */ sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1); VdbeCoverage(v); sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1); sqlite3VdbeJumpHere(v, addrGe); /* If the BIGNULL flag is set for the ORDER BY, then it is required to ** consider NULL values to be larger than all other values, instead of ** the usual smaller. The VDBE opcodes OP_Ge and so on do not handle this ** (and adding that capability causes a performance regression), so ** instead if the BIGNULL flag is set then cases where either reg1 or ** reg2 are NULL are handled separately in the following block. The code ** generated is equivalent to: ** ** if( reg1 IS NULL ){ ** if( op==OP_Ge ) goto lbl; ** if( op==OP_Gt && reg2 IS NOT NULL ) goto lbl; ** if( op==OP_Le && reg2 IS NULL ) goto lbl; ** }else if( reg2 IS NULL ){ ** if( op==OP_Le ) goto lbl; ** } ** ** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is ** not taken, control jumps over the comparison operator coded below this ** block. */ if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_BIGNULL ){ /* This block runs if reg1 contains a NULL. */ int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); switch( op ){ case OP_Ge: sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); break; case OP_Gt: sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); VdbeCoverage(v); break; case OP_Le: sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); break; default: assert( op==OP_Lt ); /* no-op */ break; } sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3); /* This block runs if reg1 is not NULL, but reg2 is. */ sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); if( op==OP_Gt || op==OP_Ge ){ sqlite3VdbeChangeP2(v, -1, sqlite3VdbeCurrentAddr(v)+1); } } /* Compare registers reg2 and reg1, taking the jump if required. Note that ** control skips over this test if the BIGNULL flag is set and either ** reg1 or reg2 contain a NULL value. */ sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le ); testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge); testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt); testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le); testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt); sqlite3ReleaseTempReg(pParse, reg1); sqlite3ReleaseTempReg(pParse, reg2); VdbeModuleComment((v, "CodeRangeTest: end")); } /* ** Helper function for sqlite3WindowCodeStep(). Each call to this function ** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE ** operation. Refer to the header comment for sqlite3WindowCodeStep() for ** details. |
︙ | ︙ | |||
2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 | */ 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->pFunc = p->pFunc; pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); pNew->eFrmType = p->eFrmType; pNew->eEnd = p->eEnd; pNew->eStart = p->eStart; pNew->eExclude = p->eExclude; pNew->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 | > > > | 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 | */ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ Window *pNew = 0; if( ALWAYS(p) ){ pNew = sqlite3DbMallocZero(db, sizeof(Window)); if( pNew ){ pNew->zName = sqlite3DbStrDup(db, p->zName); pNew->zBase = sqlite3DbStrDup(db, p->zBase); pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); pNew->pFunc = p->pFunc; pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); pNew->eFrmType = p->eFrmType; pNew->eEnd = p->eEnd; pNew->eStart = p->eStart; pNew->eExclude = p->eExclude; pNew->regResult = p->regResult; pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); pNew->pOwner = pOwner; pNew->bImplicitFrame = p->bImplicitFrame; } } return pNew; } /* ** Return a copy of the linked list of Window objects passed as the |
︙ | ︙ | |||
2559 2560 2561 2562 2563 2564 2565 | windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE ? 3 : 0)); } if( regEnd ){ sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0)); } | | | 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 | windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE ? 3 : 0)); } if( regEnd ){ sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0)); } if( pMWin->eFrmType!=TK_RANGE && pMWin->eStart==pMWin->eEnd && regStart ){ int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le); int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd); VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound <expr> */ VdbeCoverageNeverNullIf(v, op==OP_Le); /* values previously checked */ windowAggFinal(&s, 0); sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1); VdbeCoverageNeverTaken(v); |
︙ | ︙ |
Changes to test/affinity2.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is type affinity in comparison operations. # set testdir [file dirname $argv0] source $testdir/tester.tcl do_execsql_test affinity2-100 { CREATE TABLE t1( xi INTEGER, xr REAL, xb BLOB, xn NUMERIC, | > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is type affinity in comparison operations. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix affinity2 do_execsql_test affinity2-100 { CREATE TABLE t1( xi INTEGER, xr REAL, xb BLOB, xn NUMERIC, |
︙ | ︙ | |||
53 54 55 56 57 58 59 60 61 | do_execsql_test affinity2-220 { SELECT rowid, xn==xt, xn==xb, xn==+xt FROM t1 ORDER BY rowid; } {1 1 1 1 2 1 1 1 3 1 1 1} do_execsql_test affinity2-300 { SELECT rowid, xt==+xi, xt==xi, xt==xb FROM t1 ORDER BY rowid; } {1 1 1 0 2 1 1 1 3 0 1 1} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 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 | do_execsql_test affinity2-220 { SELECT rowid, xn==xt, xn==xb, xn==+xt FROM t1 ORDER BY rowid; } {1 1 1 1 2 1 1 1 3 1 1 1} do_execsql_test affinity2-300 { SELECT rowid, xt==+xi, xt==xi, xt==xb FROM t1 ORDER BY rowid; } {1 1 1 0 2 1 1 1 3 0 1 1} #------------------------------------------------------------------------- do_execsql_test 400 { CREATE TABLE ttt(c0, c1); CREATE INDEX ii ON ttt(CAST(c0 AS NUMERIC)); INSERT INTO ttt VALUES('abc', '-1'); } do_execsql_test 410 { SELECT * FROM ttt WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid; } {abc -1} do_execsql_test 420 { SELECT * FROM ttt INDEXED BY ii WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid; } {abc -1} do_execsql_test 430 { CREATE TABLE t3(a, b, c INTEGER); CREATE INDEX t3ac ON t3(a, c-1); INSERT INTO t3 VALUES(1, 1, 1); INSERT INTO t3 VALUES(2, 1, 0); INSERT INTO t3 VALUES(3, 1, 1); INSERT INTO t3 VALUES(4, 1, 0); INSERT INTO t3 VALUES(5, 1, 1); } do_execsql_test 440 { SELECT * FROM t3 WHERE c='0' ORDER BY a; } {2 1 0 4 1 0} # 2019-08-22 ticket https://sqlite.org/src/info/d99f1ffe836c591ac57f # False positive in sqlite3ExprNeedsNoAffinityChange() # do_execsql_test 500 { DROP TABLE IF EXISTS t0; CREATE TABLE t0(c0 TEXT UNIQUE, c1); INSERT INTO t0(c0) VALUES (-1); SELECT quote(- x'ce'), quote(t0.c0), quote(- x'ce' >= t0.c0) FROM t0; } {0 '-1' 1} do_execsql_test 501 { SELECT * FROM t0 WHERE - x'ce' >= t0.c0; } {-1 {}} do_execsql_test 502 { SELECT quote(+-+x'ce'), quote(t0.c0), quote(+-+x'ce' >= t0.c0) FROM t0; } {0 '-1' 1} do_execsql_test 503 { SELECT * FROM t0 WHERE +-+x'ce' >= t0.c0; } {-1 {}} do_execsql_test 504 { SELECT quote(- 'ce'), quote(t0.c0), quote(- 'ce' >= t0.c0) FROM t0; } {0 '-1' 1} do_execsql_test 505 { SELECT * FROM t0 WHERE - 'ce' >= t0.c0; } {-1 {}} do_execsql_test 506 { SELECT quote(+-+'ce'), quote(t0.c0), quote(+-+'ce' >= t0.c0) FROM t0; } {0 '-1' 1} do_execsql_test 507 { SELECT * FROM t0 WHERE +-+'ce' >= t0.c0; } {-1 {}} # 2019-08-30 ticket https://www.sqlite.org/src/info/40812aea1fde9594 # do_execsql_test 600 { DROP TABLE IF EXISTS t0; CREATE TABLE t0(c0 REAL UNIQUE); INSERT INTO t0(c0) VALUES (3175546974276630385); SELECT 3175546974276630385 < c0 FROM t0; } {1} do_execsql_test 601 { SELECT 1 FROM t0 WHERE 3175546974276630385 < c0; } {1} finish_test |
Changes to test/aggnested.test.
|
| | | 1 2 3 4 5 6 7 8 | # 2012-08-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. |
︙ | ︙ | |||
228 229 230 231 232 233 234 | do_test aggnested-3.16 { db eval { SELECT max(value1), (SELECT sum(value2=value1) FROM t2) FROM t1 GROUP BY id1; } } {12 2 34 4} | | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | do_test aggnested-3.16 { db eval { SELECT max(value1), (SELECT sum(value2=value1) FROM t2) FROM t1 GROUP BY id1; } } {12 2 34 4} # 2019-08-31 # Problem found by dbsqlfuzz # do_execsql_test aggnested-4.1 { DROP TABLE IF EXISTS aa; DROP TABLE IF EXISTS bb; CREATE TABLE aa(x INT); INSERT INTO aa(x) VALUES(123); CREATE TABLE bb(y INT); INSERT INTO bb(y) VALUES(456); SELECT (SELECT sum(x+(SELECT y)) FROM bb) FROM aa; } {579} do_execsql_test aggnested-4.2 { SELECT (SELECT sum(x+y) FROM bb) FROM aa; } {579} do_execsql_test aggnested-4.3 { DROP TABLE IF EXISTS tx; DROP TABLE IF EXISTS ty; CREATE TABLE tx(x INT); INSERT INTO tx VALUES(1),(2),(3),(4),(5); CREATE TABLE ty(y INT); INSERT INTO ty VALUES(91),(92),(93); SELECT min((SELECT count(y) FROM ty)) FROM tx; } {3} do_execsql_test aggnested-4.4 { SELECT max((SELECT a FROM (SELECT count(*) AS a FROM ty) AS s)) FROM tx; } {3} finish_test |
Changes to test/alter.test.
︙ | ︙ | |||
852 853 854 855 856 857 858 | #------------------------------------------------------------------------- # Test that it is not possible to use ALTER TABLE on any system table. # set system_table_list {1 sqlite_master} catchsql ANALYZE ifcapable analyze { lappend system_table_list 2 sqlite_stat1 } | < | 852 853 854 855 856 857 858 859 860 861 862 863 864 865 | #------------------------------------------------------------------------- # Test that it is not possible to use ALTER TABLE on any system table. # set system_table_list {1 sqlite_master} catchsql ANALYZE ifcapable analyze { lappend system_table_list 2 sqlite_stat1 } ifcapable stat4 { lappend system_table_list 4 sqlite_stat4 } foreach {tn tbl} $system_table_list { do_test alter-15.$tn.1 { catchsql "ALTER TABLE $tbl RENAME TO xyz" } [list 1 "table $tbl may not be altered"] |
︙ | ︙ |
Changes to test/altertab.test.
︙ | ︙ | |||
590 591 592 593 594 595 596 | ALTER TABLE t0 RENAME COLUMN c0 TO c1; } do_execsql_test 18.2.2 { SELECT sql FROM sqlite_master; } {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1))}} finish_test | < | 590 591 592 593 594 595 596 | ALTER TABLE t0 RENAME COLUMN c0 TO c1; } do_execsql_test 18.2.2 { SELECT sql FROM sqlite_master; } {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1))}} finish_test |
Changes to test/altertab3.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | set testprefix altertab3 # If SQLITE_OMIT_ALTERTABLE is defined, omit this file. ifcapable !altertable { finish_test return } ifcapable windowfunc { do_execsql_test 1.0 { CREATE TABLE t1(a, b); CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT sum(b) OVER w FROM t1 WINDOW w AS (ORDER BY a); END; | > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | set testprefix altertab3 # If SQLITE_OMIT_ALTERTABLE is defined, omit this file. ifcapable !altertable { finish_test return } ifcapable windowfunc { do_execsql_test 1.0 { CREATE TABLE t1(a, b); CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT sum(b) OVER w FROM t1 WINDOW w AS (ORDER BY a); END; |
︙ | ︙ | |||
232 233 234 235 236 237 238 239 240 241 | ALTER TABLE t2 RENAME TO t3; SELECT sql FROM sqlite_master WHERE name='v1'; } { {CREATE VIEW v1 AS SELECT * FROM t1 WHERE ( SELECT t1.a FROM t1, t2 ) IN () OR t1.a=5} } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | ALTER TABLE t2 RENAME TO t3; SELECT sql FROM sqlite_master WHERE name='v1'; } { {CREATE VIEW v1 AS SELECT * FROM t1 WHERE ( SELECT t1.a FROM t1, t2 ) IN () OR t1.a=5} } #------------------------------------------------------------------------- reset_db do_execsql_test 11.1 { CREATE TABLE t1( a,b,c,d,e,f,g,h,j,jj,jjb,k,aa,bb,cc,dd,ee DEFAULT 3.14, ff DEFAULT('hiccup'),Wg NOD NULL DEFAULT(false) ); CREATE TRIGGER b AFTER INSERT ON t1 WHEN new.a BEGIN SELECT a, sum() w3 FROM t1 WINDOW b AS (ORDER BY NOT EXISTS(SELECT 1 FROM abc)); END; } do_catchsql_test 11.2 { ALTER TABLE t1 RENAME TO t1x; } {1 {error in trigger b: no such table: abc}} do_execsql_test 11.3 { DROP TRIGGER b; CREATE TRIGGER b AFTER INSERT ON t1 WHEN new.a BEGIN SELECT a, sum() w3 FROM t1 WINDOW b AS (ORDER BY NOT EXISTS(SELECT 1 FROM t1)); END; } {} do_execsql_test 11.4 { ALTER TABLE t1 RENAME TO t1x; SELECT sql FROM sqlite_master WHERE name = 'b'; } { {CREATE TRIGGER b AFTER INSERT ON "t1x" WHEN new.a BEGIN SELECT a, sum() w3 FROM "t1x" WINDOW b AS (ORDER BY NOT EXISTS(SELECT 1 FROM "t1x")); END} } #------------------------------------------------------------------------- reset_db do_execsql_test 12.1 { CREATE TABLE t1(a,b,c,d,e,f,g,h,j,jj,Zjj,k,aQ,bb,cc,dd,ee DEFAULT 3.14, ff DEFAULT('hiccup'),gg NOD NULL DEFAULT(false)); CREATE TRIGGER AFTER INSERT ON t1 WHEN new.a NOT NULL BEGIN SELECT b () OVER , dense_rank() OVER d, d () OVER w1 FROM t1 WINDOW w1 AS ( w1 ORDER BY d ROWS BETWEEN 2 NOT IN(SELECT a, sum(d) w2,max(d)OVER FROM t1 WINDOW w1 AS (PARTITION BY d ROWS BETWEEN '' PRECEDING AND false FOLLOWING), d AS (PARTITION BY b ORDER BY d ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) ) PRECEDING AND 1 FOLLOWING), w2 AS (PARTITION BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), w3 AS (PARTITION BY b ORDER BY d ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) ; SELECT a, sum(d) w2,max(d)OVER FROM t1 WINDOW w1 AS (PARTITION BY d ROWS BETWEEN '' PRECEDING AND false FOLLOWING), d AS (PARTITION BY b ORDER BY d ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) ; END; } do_execsql_test 12.2 { ALTER TABLE t1 RENAME TO t1x; } #------------------------------------------------------------------------- reset_db do_execsql_test 13.1 { CREATE TABLE t1(a); CREATE TRIGGER r1 INSERT ON t1 BEGIN SELECT a(*) OVER (ORDER BY (SELECT 1)) FROM t1; END; } do_execsql_test 13.2 { ALTER TABLE t1 RENAME TO t1x; } #------------------------------------------------------------------------- reset_db do_execsql_test 14.1 { CREATE TABLE t1(a); CREATE TABLE t2(b); CREATE TRIGGER AFTER INSERT ON t1 BEGIN SELECT sum() FILTER (WHERE (SELECT sum() FILTER (WHERE 0)) AND a); END; } do_catchsql_test 14.2 { ALTER TABLE t1 RENAME TO t1x; } {1 {error in trigger AFTER: no such column: a}} #------------------------------------------------------------------------- reset_db do_execsql_test 16.1 { CREATE TABLE t1(x); CREATE TRIGGER AFTER INSERT ON t1 BEGIN SELECT (WITH t2 AS (WITH t3 AS (SELECT true) SELECT * FROM t3 ORDER BY true COLLATE nocase) SELECT 11); WITH t4 AS (SELECT * FROM t1) SELECT 33; END; } do_execsql_test 16.2 { ALTER TABLE t1 RENAME TO t1x; } #------------------------------------------------------------------------- reset_db do_execsql_test 17.1 { CREATE TABLE t1(a,b,c); CREATE TRIGGER AFTER INSERT ON t1 WHEN new.a NOT NULL BEGIN SELECT a () FILTER (WHERE a>0) FROM t1; END; } do_execsql_test 17.2 { ALTER TABLE t1 RENAME TO t1x; ALTER TABLE t1x RENAME a TO aaa; SELECT sql FROM sqlite_master WHERE type='trigger'; } { {CREATE TRIGGER AFTER INSERT ON "t1x" WHEN new.aaa NOT NULL BEGIN SELECT a () FILTER (WHERE aaa>0) FROM "t1x"; END} } finish_test |
Changes to test/analyze.test.
︙ | ︙ | |||
284 285 286 287 288 289 290 | sqlite3 db test.db execsql { SELECT * FROM t4 WHERE x=1234; } } {} # Verify that DROP TABLE and DROP INDEX remove entries from the | | | < | | | < > | | | | < > | | | | < > | 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | sqlite3 db test.db execsql { SELECT * FROM t4 WHERE x=1234; } } {} # Verify that DROP TABLE and DROP INDEX remove entries from the # sqlite_stat1 and sqlite_stat4 tables. # do_test analyze-5.0 { execsql { DELETE FROM t3; DELETE FROM t4; INSERT INTO t3 VALUES(1,2,3,4); INSERT INTO t3 VALUES(5,6,7,8); INSERT INTO t3 SELECT a+8, b+8, c+8, d+8 FROM t3; INSERT INTO t3 SELECT a+16, b+16, c+16, d+16 FROM t3; INSERT INTO t3 SELECT a+32, b+32, c+32, d+32 FROM t3; INSERT INTO t3 SELECT a+64, b+64, c+64, d+64 FROM t3; INSERT INTO t4 SELECT a, b, c FROM t3; ANALYZE; SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1; SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1; } } {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4} ifcapable stat4 { do_test analyze-5.1 { execsql { SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1; SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1; } } {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4} } do_test analyze-5.2 { execsql { DROP INDEX t3i2; SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1; SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1; } } {t3i1 t3i3 t4i1 t4i2 t3 t4} ifcapable stat4 { do_test analyze-5.3 { execsql { SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1; SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1; } } {t3i1 t3i3 t4i1 t4i2 t3 t4} } do_test analyze-5.4 { execsql { DROP TABLE t3; SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1; SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1; } } {t4i1 t4i2 t4} ifcapable stat4 { do_test analyze-5.5 { execsql { SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1; SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1; } } {t4i1 t4i2 t4} } # This test corrupts the database file so it must be the last test # in the series. # do_test analyze-5.99 { |
︙ | ︙ |
Changes to test/analyze3.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 | # instead of literal constant arguments. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix analyze3 | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # instead of literal constant arguments. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix analyze3 ifcapable !stat4 { finish_test return } #---------------------------------------------------------------------- # Test Organization: # |
︙ | ︙ | |||
96 97 98 99 100 101 102 | execsql { INSERT INTO t1 VALUES($i+100, $i) } } execsql { COMMIT; ANALYZE; } | < | < < < | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | execsql { INSERT INTO t1 VALUES($i+100, $i) } } execsql { COMMIT; ANALYZE; } execsql { SELECT count(*)>0 FROM sqlite_stat4; } } {1} do_execsql_test analyze3-1.1.x { SELECT count(*) FROM t1 WHERE x>200 AND x<300; SELECT count(*) FROM t1 WHERE x>0 AND x<1100; } {99 1000} |
︙ | ︙ |
Changes to test/analyze5.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 | # in this file is the use of the sqlite_stat4 histogram data on tables # with many repeated values and only a few distinct values. # set testdir [file dirname $argv0] source $testdir/tester.tcl | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # in this file is the use of the sqlite_stat4 histogram data on tables # with many repeated values and only a few distinct values. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !stat4 { finish_test return } set testprefix analyze5 proc eqp {sql {db db}} { |
︙ | ︙ | |||
63 64 65 66 67 68 69 | CREATE INDEX t1v ON t1(v); -- mixed case text CREATE INDEX t1w ON t1(w); -- integers 0, 1, 2 and a few NULLs CREATE INDEX t1x ON t1(x); -- integers 1, 2, 3 and many NULLs CREATE INDEX t1y ON t1(y); -- integers 0 and very few 1s CREATE INDEX t1z ON t1(z); -- integers 0, 1, 2, and 3 ANALYZE; } | < | | | < < < < < < | | | | < < < < < < | | | < < < < < | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | CREATE INDEX t1v ON t1(v); -- mixed case text CREATE INDEX t1w ON t1(w); -- integers 0, 1, 2 and a few NULLs CREATE INDEX t1x ON t1(x); -- integers 1, 2, 3 and many NULLs CREATE INDEX t1y ON t1(y); -- integers 0 and very few 1s CREATE INDEX t1z ON t1(z); -- integers 0, 1, 2, and 3 ANALYZE; } db eval { SELECT DISTINCT lindex(test_decode(sample),0) FROM sqlite_stat4 WHERE idx='t1u' ORDER BY nlt; } } {alpha bravo charlie delta} do_test analyze5-1.1 { db eval { SELECT DISTINCT lower(lindex(test_decode(sample), 0)) FROM sqlite_stat4 WHERE idx='t1v' ORDER BY 1 } } {alpha bravo charlie delta} do_test analyze5-1.2 { db eval {SELECT idx, count(*) FROM sqlite_stat4 GROUP BY 1 ORDER BY 1} } {t1t 8 t1u 8 t1v 8 t1w 8 t1x 8 t1y 9 t1z 8} # Verify that range queries generate the correct row count estimates # foreach {testid where index rows} { 1 {z>=0 AND z<=0} t1z 400 2 {z>=1 AND z<=1} t1z 300 3 {z>=2 AND z<=2} t1z 175 |
︙ | ︙ |
Changes to test/analyze6.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 | # in this file a corner-case query planner optimization involving the # join order of two tables of different sizes. # set testdir [file dirname $argv0] source $testdir/tester.tcl | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # in this file a corner-case query planner optimization involving the # join order of two tables of different sizes. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !stat4 { finish_test return } set testprefix analyze6 proc eqp {sql {db db}} { |
︙ | ︙ |
Changes to test/analyze7.test.
︙ | ︙ | |||
78 79 80 81 82 83 84 | } {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} do_test analyze7-3.1 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;} } {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/} do_test analyze7-3.2.1 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;} } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/} | | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | } {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} do_test analyze7-3.1 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;} } {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/} do_test analyze7-3.2.1 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;} } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/} ifcapable stat4 { # If ENABLE_STAT4 is defined, SQLite comes up with a different estimated # row count for (c=2) than it does for (c=?). do_test analyze7-3.2.2 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;} } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/} } else { # If ENABLE_STAT4 is not defined, the expected row count for (c=2) is the # same as that for (c=?). do_test analyze7-3.2.3 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;} } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/} } do_test analyze7-3.3 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123} } {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} ifcapable {!stat4} { do_test analyze7-3.4 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND b=123} } {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/} do_test analyze7-3.5 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND c=123} } {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/} } do_test analyze7-3.6 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND d=123 AND b=123} } {/*SEARCH TABLE t1 USING INDEX t1cd (c=? AND d=?)*/} finish_test |
Changes to test/analyze8.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2011 August 13 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file implements tests for SQLite library. The focus of the tests | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # 2011 August 13 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file implements tests for SQLite library. The focus of the tests # in this file is testing the capabilities of sqlite_stat4. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !stat4 { finish_test return } set testprefix analyze8 proc eqp {sql {db db}} { |
︙ | ︙ |
Deleted test/analyzeA.test.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted test/analyzeB.test.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to test/analyzeC.test.
︙ | ︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 139 140 | ANALYZE sqlite_master; SELECT count(a) FROM t1; } {6} do_execsql_test 4.3 { EXPLAIN QUERY PLAN SELECT count(a) FROM t1; } {/.*INDEX t1ca.*/} # The sz=NNN parameter works even if there is other extraneous text # in the sqlite_stat1.stat column. # do_execsql_test 5.0 { DELETE FROM sqlite_stat1; | > > > > > > > > > > > > > > | 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 | ANALYZE sqlite_master; SELECT count(a) FROM t1; } {6} do_execsql_test 4.3 { EXPLAIN QUERY PLAN SELECT count(a) FROM t1; } {/.*INDEX t1ca.*/} # 2019-08-15. # Ticket https://www.sqlite.org/src/tktview/e4598ecbdd18bd82945f602901 # The sz=N parameter in the sqlite_stat1 table needs to have a value of # 2 or more to avoid a division by zero in the query planner. # do_execsql_test 4.4 { DROP TABLE IF EXISTS t44; CREATE TABLE t44(a PRIMARY KEY); INSERT INTO sqlite_stat1 VALUES('t44',null,'sz=0'); ANALYZE sqlite_master; SELECT 0 FROM t44 WHERE a IN(1,2,3); } {} # The sz=NNN parameter works even if there is other extraneous text # in the sqlite_stat1.stat column. # do_execsql_test 5.0 { DELETE FROM sqlite_stat1; |
︙ | ︙ |
Changes to test/auth.test.
︙ | ︙ | |||
2446 2447 2448 2449 2450 2451 2452 | DROP TABLE v1chng; } } } ifcapable stat4 { set stat4 "sqlite_stat4 " } else { | < < < | < | 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 | DROP TABLE v1chng; } } } ifcapable stat4 { set stat4 "sqlite_stat4 " } else { set stat4 "" } do_test auth-5.2 { execsql { SELECT name FROM ( SELECT * FROM sqlite_master UNION ALL SELECT * FROM temp.sqlite_master) WHERE type='table' ORDER BY name |
︙ | ︙ |
Changes to test/check.test.
︙ | ︙ | |||
119 120 121 122 123 124 125 126 127 128 129 130 131 132 | execsql { PRAGMA writable_schema = 1; CREATE TABLE t2( x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ), y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ), z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' ) ); PRAGMA writable_schema = 0; } } {} do_test check-2.2 { execsql { INSERT INTO t2 VALUES(1,2.2,'three'); SELECT * FROM t2; | > > > > > | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | execsql { PRAGMA writable_schema = 1; CREATE TABLE t2( x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ), y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ), z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' ) ); CREATE TABLE t2n( x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ), y NUMERIC CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ), z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' ) ); PRAGMA writable_schema = 0; } } {} do_test check-2.2 { execsql { INSERT INTO t2 VALUES(1,2.2,'three'); SELECT * FROM t2; |
︙ | ︙ | |||
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | } {1 2.2 three {} {} {}} do_test check-2.4 { catchsql { INSERT INTO t2 VALUES(1.1, NULL, NULL); } } {1 {CHECK constraint failed: one}} do_test check-2.5 { catchsql { INSERT INTO t2 VALUES(NULL, 5, NULL); } } {1 {CHECK constraint failed: two}} do_test check-2.6 { catchsql { INSERT INTO t2 VALUES(NULL, NULL, 3.14159); } } {1 {CHECK constraint failed: three}} | > > > > > > > > | 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 | } {1 2.2 three {} {} {}} do_test check-2.4 { catchsql { INSERT INTO t2 VALUES(1.1, NULL, NULL); } } {1 {CHECK constraint failed: one}} do_test check-2.5 { # The 5 gets automatically promoted to 5.0 because the column type is REAL catchsql { INSERT INTO t2 VALUES(NULL, 5, NULL); } } {0 {}} do_test check-2.5b { # This time the column type is NUMERIC, so not automatic promption to REAL # occurs and the constraint fails. catchsql { INSERT INTO t2n VALUES(NULL, 5, NULL); } } {1 {CHECK constraint failed: two}} do_test check-2.6 { catchsql { INSERT INTO t2 VALUES(NULL, NULL, 3.14159); } } {1 {CHECK constraint failed: three}} |
︙ | ︙ | |||
191 192 193 194 195 196 197 198 199 200 201 202 203 204 | INSERT INTO t2c VALUES('xyzzy',7,8); } } {1 {CHECK constraint failed: x_two}} do_test check-2.cleanup { execsql { DROP TABLE IF EXISTS t2b; DROP TABLE IF EXISTS t2c; } } {} ifcapable subquery { do_test check-3.1 { catchsql { CREATE TABLE t3( | > | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | INSERT INTO t2c VALUES('xyzzy',7,8); } } {1 {CHECK constraint failed: x_two}} do_test check-2.cleanup { execsql { DROP TABLE IF EXISTS t2b; DROP TABLE IF EXISTS t2c; DROP TABLE IF EXISTS t2n; } } {} ifcapable subquery { do_test check-3.1 { catchsql { CREATE TABLE t3( |
︙ | ︙ | |||
490 491 492 493 494 495 496 497 498 | forcedelete test.db sqlite3 db test.db do_execsql_test 10.1 { CREATE TABLE t1(x); CREATE VIEW v1(y) AS SELECT x FROM t1; PRAGMA integrity_check; } {ok} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 | forcedelete test.db sqlite3 db test.db do_execsql_test 10.1 { CREATE TABLE t1(x); CREATE VIEW v1(y) AS SELECT x FROM t1; PRAGMA integrity_check; } {ok} #------------------------------------------------------------------------- reset_db do_execsql_test 11.0 { CREATE TABLE t1 (Col0 CHECK(1 COLLATE BINARY BETWEEN 1 AND 1) ) ; } do_execsql_test 11.1 { INSERT INTO t1 VALUES (NULL); } do_execsql_test 11.2 { INSERT INTO t1 VALUES (NULL); } do_execsql_test 11.3 { CREATE TABLE t2(b, a CHECK( CASE 'abc' COLLATE nocase WHEN a THEN 1 ELSE 0 END) ); } do_execsql_test 11.4 { INSERT INTO t2(a) VALUES('abc'); } do_execsql_test 11.5 { INSERT INTO t2(b, a) VALUES(1, 'abc'||''); } do_execsql_test 11.6 { INSERT INTO t2(b, a) VALUES(2, 'abc'); } finish_test finish_test |
Added test/checkfault.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | # 2019 July 17 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains fault-injection test cases for the # sqlite3_db_cacheflush API. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix cffault source $testdir/malloc_common.tcl do_execsql_test 1.0 { CREATE TABLE t1 (Col0 CHECK(1 COLLATE BINARY BETWEEN 1 AND 1) ) ; CREATE TABLE t2(b, a CHECK( CASE 'abc' COLLATE nocase WHEN a THEN 1 ELSE 0 END) ); } do_faultsim_test 1.1 -faults oom* -body { execsql { INSERT INTO t1 VALUES ('ABCDEFG') } } -test { faultsim_test_result {0 {}} } do_faultsim_test 1.2 -faults oom* -body { execsql { INSERT INTO t2(a) VALUES('abc') } } -test { faultsim_test_result {0 {}} } finish_test |
Changes to test/close.test.
︙ | ︙ | |||
74 75 76 77 78 79 80 81 82 | sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 dummy } msg] $msg } {1 {(21) bad parameter or other API misuse}} do_test 1.4.4 { sqlite3_finalize $STMT } {SQLITE_OK} finish_test | > > > > > > > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 dummy } msg] $msg } {1 {(21) bad parameter or other API misuse}} do_test 1.4.4 { sqlite3_finalize $STMT } {SQLITE_OK} do_test 1.5 { set DB [sqlite3_open test.db] sqlite3_blob_open $DB main t1 x 2 0 BLOB sqlite3_close_v2 $DB sqlite3_blob_close $BLOB } {} finish_test |
Changes to test/colname.test.
︙ | ︙ | |||
395 396 397 398 399 400 401 402 403 404 405 406 407 408 | } {Bbb 123} ifcapable vtab { do_execsql_test colname-9.320 { CREATE TABLE t2 AS SELECT BBb FROM (SELECT aaa AS Bbb FROM t1); SELECT name FROM pragma_table_info('t2'); } {Bbb} } # 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. # | > > > > > > | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 | } {Bbb 123} ifcapable vtab { do_execsql_test colname-9.320 { CREATE TABLE t2 AS SELECT BBb FROM (SELECT aaa AS Bbb FROM t1); SELECT name FROM pragma_table_info('t2'); } {Bbb} } do_execsql_test colname-9.330 { -- added 2019-08-10 to invalidate DROP TABLE IF EXISTS t1; -- a couple assert()s that were CREATE TABLE t1(a); -- added by ticket 3b44500725 INSERT INTO t1 VALUES(17),(2),(99),(-3),(7); SELECT (SELECT avg(a) UNION SELECT min(a) OVER()) FROM t1; } {17} # Issue detected by OSSFuzz on 2017-12-24 (Christmas Eve) # caused by check-in https://sqlite.org/src/info/6b2ff26c25 # # Prior to being fixed, the following CREATE TABLE was dereferencing # a NULL pointer and segfaulting. # |
︙ | ︙ |
Changes to test/conflict3.test.
︙ | ︙ | |||
362 363 364 365 366 367 368 369 370 | do_execsql_test 12.2 { REPLACE INTO t2 VALUES(NULL, '112'), (111, '111B'); } do_execsql_test 12.3 { SELECT * FROM t2; } {111 111B 112 112} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | do_execsql_test 12.2 { REPLACE INTO t2 VALUES(NULL, '112'), (111, '111B'); } do_execsql_test 12.3 { SELECT * FROM t2; } {111 111B 112 112} #------------------------------------------------------------------------- ifcapable trigger { reset_db do_execsql_test 13.1.0 { PRAGMA recursive_triggers = true; CREATE TABLE t0 (c0 UNIQUE, c1 UNIQUE); CREATE TRIGGER tr0 AFTER DELETE ON t0 BEGIN DELETE FROM t0; END; INSERT INTO t0 VALUES(1, NULL); INSERT INTO t0 VALUES(0, NULL); } do_execsql_test 13.1.1 { UPDATE OR REPLACE t0 SET c1 = 1; } integrity_check 13.1.2 do_execsql_test 13.1.3 { SELECT * FROM t0 } {} do_execsql_test 13.2.0 { CREATE TABLE t2 (a PRIMARY KEY, b UNIQUE, c UNIQUE) WITHOUT ROWID; CREATE TRIGGER tr3 AFTER DELETE ON t2 BEGIN DELETE FROM t2; END; INSERT INTO t2 VALUES(1, 1, 1); INSERT INTO t2 VALUES(2, 2, 2); } do_execsql_test 13.2.1 { UPDATE OR REPLACE t2 SET c = 0; } integrity_check 13.2.2 do_execsql_test 13.2.3 { SELECT * FROM t2 } {} do_execsql_test 13.3.0 { CREATE TABLE t1(a, b); CREATE TABLE log(x); CREATE INDEX i1 ON t1(a); INSERT INTO t1 VALUES(1, 2); CREATE TRIGGER tb BEFORE UPDATE ON t1 BEGIN DELETE FROM t1; END; CREATE TRIGGER ta AFTER UPDATE ON t1 BEGIN INSERT INTO log VALUES('fired!'); END; UPDATE t1 SET b=3; } do_execsql_test 13.3.1 { SELECT * FROM t1; } {} do_execsql_test 13.3.2 { SELECT * FROM log; } {} } finish_test |
Changes to test/corruptL.test.
︙ | ︙ | |||
224 225 226 227 228 229 230 231 232 233 234 235 236 237 | | 4080: 01 04 04 03 08 01 13 04 03 08 01 02 03 03 08 09 ................ | page 5 offset 16384 | 0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 ................ | end crash.txt.db }]} {} do_execsql_test 2.1 { INSERT INTO t1(b) VALUES(X'a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bfef346e6ac8ae0d0e7c3175946e62ba2b'); } do_catchsql_test 2.2 { SELECT b,c FROM t1 ORDER BY a; } {1 {database disk image is malformed}} | > | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | | 4080: 01 04 04 03 08 01 13 04 03 08 01 02 03 03 08 09 ................ | page 5 offset 16384 | 0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 ................ | end crash.txt.db }]} {} do_execsql_test 2.1 { PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking INSERT INTO t1(b) VALUES(X'a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bfef346e6ac8ae0d0e7c3175946e62ba2b'); } do_catchsql_test 2.2 { SELECT b,c FROM t1 ORDER BY a; } {1 {database disk image is malformed}} |
︙ | ︙ | |||
373 374 375 376 377 378 379 380 381 382 383 384 385 386 | | 464: 05 01 01 09 09 02 02 19 04 05 17 17 17 17 10 65 ...............e | 480: 76 65 6e 65 69 67 68 74 65 40 18 00 00 00 00 01 veneighte@...... | 496: 02 03 07 04 01 01 01 03 04 02 05 04 09 01 ff fd ................ | end crash-6b48ba69806134.db }]} {} do_catchsql_test 4.1 { INSERT INTO t3 SELECT * FROM t2; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 5.0 { | > | 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | | 464: 05 01 01 09 09 02 02 19 04 05 17 17 17 17 10 65 ...............e | 480: 76 65 6e 65 69 67 68 74 65 40 18 00 00 00 00 01 veneighte@...... | 496: 02 03 07 04 01 01 01 03 04 02 05 04 09 01 ff fd ................ | end crash-6b48ba69806134.db }]} {} do_catchsql_test 4.1 { PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking INSERT INTO t3 SELECT * FROM t2; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 5.0 { |
︙ | ︙ | |||
601 602 603 604 605 606 607 | | 3808: 05 43 52 45 41 54 45 20 49 4e 44 45 58 20 74 31 .CREATE INDEX t1 | 3824: 62 20 4f 4e 20 74 31 28 62 29 50 03 06 17 2b 2b b ON t1(b)P...++ | 3840: 01 59 74 61 62 6c 65 73 71 6c 69 74 65 5f 73 65 .Ytablesqlite_se | 3856: 71 75 65 6e 63 65 73 71 6c 69 74 65 5f 73 65 71 quencesqlite_seq | 3872: 75 65 6e 63 65 04 43 52 45 41 54 45 20 54 41 42 uence.CREATE TAB | 3888: 4c 45 20 73 71 6c 69 74 65 5f 73 65 71 75 65 6e LE sqlite_sequen | 3904: 63 65 28 6e 61 6d 65 2c 73 65 71 29 81 04 01 07 ce(name,seq).... | | | 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 | | 3808: 05 43 52 45 41 54 45 20 49 4e 44 45 58 20 74 31 .CREATE INDEX t1 | 3824: 62 20 4f 4e 20 74 31 28 62 29 50 03 06 17 2b 2b b ON t1(b)P...++ | 3840: 01 59 74 61 62 6c 65 73 71 6c 69 74 65 5f 73 65 .Ytablesqlite_se | 3856: 71 75 65 6e 63 65 73 71 6c 69 74 65 5f 73 65 71 quencesqlite_seq | 3872: 75 65 6e 63 65 04 43 52 45 41 54 45 20 54 41 42 uence.CREATE TAB | 3888: 4c 45 20 73 71 6c 69 74 65 5f 73 65 71 75 65 6e LE sqlite_sequen | 3904: 63 65 28 6e 61 6d 65 2c 73 65 71 29 81 04 01 07 ce(name,seq).... | 3920: 17 11 11 01 81 73 74 61 62 6c 65 74 31 74 31 02 .....stablet1t1. | 3936: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 CREATE TABLE t1( | 3952: 61 20 52 45 41 4c 20 4e 4f 54 20 4e 55 4c 4c 20 a REAL NOT NULL | 3968: 44 45 46 41 55 4c 54 28 32 35 2b 33 32 29 2c 62 DEFAULT(25+32),b | 3984: 20 46 4c 4f 41 54 2c 63 20 44 4f 55 42 4c 45 20 FLOAT,c DOUBLE | 4000: 55 4e 49 51 55 45 2c 0a 64 20 43 4c 4f 42 2c 65 UNIQUE,.d CLOB,e | 4016: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY | 4032: 20 4b 45 59 20 41 55 54 4f 49 4e 43 52 45 4d 45 KEY AUTOINCREME |
︙ | ︙ | |||
831 832 833 834 835 836 837 838 839 840 841 842 843 844 | | page 4 offset 1536 | 0: 0d 00 39 00 00 02 00 00 00 00 00 00 00 00 00 00 ..9............. | end a.db }]} {} do_catchsql_test 8.1 { INSERT INTO t3 SELECT * FROM t2; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 9.0 { sqlite3 db {} | > | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 | | page 4 offset 1536 | 0: 0d 00 39 00 00 02 00 00 00 00 00 00 00 00 00 00 ..9............. | end a.db }]} {} do_catchsql_test 8.1 { PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking INSERT INTO t3 SELECT * FROM t2; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 9.0 { sqlite3 db {} |
︙ | ︙ | |||
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | | 2512: 00 00 00 00 00 00 00 96 00 00 00 00 00 00 00 00 ................ | page 44 offset 176128 | 2512: 00 00 00 00 00 00 00 00 aa 00 00 00 00 00 00 00 ................ | end crash-41390d95d613b6.db }]} {} do_catchsql_test 10.1 { SELECT * FROM t1 WHERE a<='2019-05-09' ORDER BY a DESC; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 11.0 { | > | 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 | | 2512: 00 00 00 00 00 00 00 96 00 00 00 00 00 00 00 00 ................ | page 44 offset 176128 | 2512: 00 00 00 00 00 00 00 00 aa 00 00 00 00 00 00 00 ................ | end crash-41390d95d613b6.db }]} {} do_catchsql_test 10.1 { PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking SELECT * FROM t1 WHERE a<='2019-05-09' ORDER BY a DESC; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 11.0 { |
︙ | ︙ | |||
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | | 48: 3f 69 33 74 6e 65 78 78 74 64 33 ff 43 52 45 a0 ?i3tnexxtd3.CRE. | 64: a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 74 13 11 01 ............t... | 80: 49 45 74 00 00 00 00 00 00 00 00 00 00 00 00 00 IEt............. | end x.db }]} {} do_catchsql_test 11.1 { DELETE FROM t3 WHERE x IN (SELECT x FROM t4); } {1 {database disk image is malformed}} finish_test | > | 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 | | 48: 3f 69 33 74 6e 65 78 78 74 64 33 ff 43 52 45 a0 ?i3tnexxtd3.CRE. | 64: a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 a0 74 13 11 01 ............t... | 80: 49 45 74 00 00 00 00 00 00 00 00 00 00 00 00 00 IEt............. | end x.db }]} {} do_catchsql_test 11.1 { PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking DELETE FROM t3 WHERE x IN (SELECT x FROM t4); } {1 {database disk image is malformed}} finish_test |
Added test/corruptM.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | # 2019-08-12 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # Check to ensure that the type, name, and tbl_name fields of the # sqlite_master table are validated and errors are reported if they # are inconsistent with the sql. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix corruptM # These tests deal with corrupt database files # database_may_be_corrupt db close forcedelete test.db sqlite3 db test.db do_execsql_test corruptM-100 { CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(111,222,333); CREATE INDEX i1 ON t1(b); CREATE VIEW v2 AS SELECT 15,22; CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN SELECT 5; END; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |} do_execsql_test corruptM-101 { PRAGMA writable_schema=on; UPDATE sqlite_master SET tbl_name=NULL WHERE name='t1'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t1 {} | index i1 t1 | view v2 v2 | trigger r1 t1 |} sqlite3 db2 test.db do_test corruptM-102 { catchsql { PRAGMA quick_check; } db2 } {1 {malformed database schema (t1)}} db2 close do_execsql_test corruptM-110 { UPDATE sqlite_master SET tbl_name='tx' WHERE name='t1'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t1 tx | index i1 t1 | view v2 v2 | trigger r1 t1 |} sqlite3 db2 test.db do_test corruptM-111 { catchsql { PRAGMA quick_check; } db2 } {1 {malformed database schema (t1)}} db2 close do_execsql_test corruptM-112 { UPDATE sqlite_master SET tbl_name='t1', type='tabl' WHERE name='t1'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {tabl t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |} sqlite3 db2 test.db do_test corruptM-113 { catchsql { PRAGMA quick_check; } db2 } {1 {malformed database schema (t1)}} db2 close do_execsql_test corruptM-114 { UPDATE sqlite_master SET tbl_name='t9',type='table',name='t9'WHERE name='t1'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t9 t9 | index i1 t1 | view v2 v2 | trigger r1 t1 |} sqlite3 db2 test.db do_test corruptM-114 { catchsql { PRAGMA quick_check; } db2 } {1 {malformed database schema (t9)}} db2 close do_execsql_test corruptM-120 { UPDATE sqlite_master SET name='t1',tbl_name='T1' WHERE name='t9'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |} sqlite3 db2 test.db do_test corruptM-121 { catchsql { PRAGMA quick_check; SELECT * FROM t1, v2; } db2 } {0 {ok 111 222 333 15 22}} db2 close do_execsql_test corruptM-130 { UPDATE sqlite_master SET type='view' WHERE name='t1'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {view t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |} sqlite3 db2 test.db do_test corruptM-131 { catchsql { PRAGMA quick_check; SELECT * FROM t1, v2; } db2 } {1 {malformed database schema (t1)}} db2 close do_execsql_test corruptM-140 { UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='t1'; UPDATE sqlite_master SET tbl_name='tx' WHERE name='i1'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t1 t1 | index i1 tx | view v2 v2 | trigger r1 t1 |} sqlite3 db2 test.db do_test corruptM-141 { catchsql { PRAGMA quick_check; SELECT * FROM t1, v2; } db2 } {1 {malformed database schema (i1)}} db2 close do_execsql_test corruptM-150 { UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='i1'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t1 t1 | table i1 t1 | view v2 v2 | trigger r1 t1 |} sqlite3 db2 test.db do_test corruptM-151 { catchsql { PRAGMA quick_check; SELECT * FROM t1, v2; } db2 } {1 {malformed database schema (i1)}} db2 close do_execsql_test corruptM-160 { UPDATE sqlite_master SET type='view', tbl_name='t1' WHERE name='i1'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t1 t1 | view i1 t1 | view v2 v2 | trigger r1 t1 |} sqlite3 db2 test.db do_test corruptM-161 { catchsql { PRAGMA quick_check; SELECT * FROM t1, v2; } db2 } {1 {malformed database schema (i1)}} db2 close do_execsql_test corruptM-170 { UPDATE sqlite_master SET type='index', tbl_name='t1' WHERE name='i1'; UPDATE sqlite_master SET type='table', tbl_name='v2' WHERE name='v2'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t1 t1 | index i1 t1 | table v2 v2 | trigger r1 t1 |} sqlite3 db2 test.db do_test corruptM-171 { catchsql { PRAGMA quick_check; SELECT * FROM t1, v2; } db2 } {1 {malformed database schema (v2)}} db2 close do_execsql_test corruptM-180 { UPDATE sqlite_master SET type='view',name='v3',tbl_name='v3' WHERE name='v2'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t1 t1 | index i1 t1 | view v3 v3 | trigger r1 t1 |} sqlite3 db2 test.db do_test corruptM-181 { catchsql { PRAGMA quick_check; SELECT * FROM t1, v2; } db2 } {1 {malformed database schema (v3)}} db2 close do_execsql_test corruptM-190 { UPDATE sqlite_master SET type='view',name='v2',tbl_name='v2' WHERE name='v3'; UPDATE sqlite_master SET type='view' WHERE name='r1'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t1 t1 | index i1 t1 | view v2 v2 | view r1 t1 |} sqlite3 db2 test.db do_test corruptM-191 { catchsql { PRAGMA quick_check; SELECT * FROM t1, v2; } db2 } {1 {malformed database schema (r1)}} db2 close do_execsql_test corruptM-192 { UPDATE sqlite_master SET type='trigger',tbl_name='v2' WHERE name='r1'; SELECT type, name, tbl_name, '|' FROM sqlite_master; } {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 v2 |} sqlite3 db2 test.db do_test corruptM-193 { catchsql { PRAGMA quick_check; SELECT * FROM t1, v2; } db2 } {1 {malformed database schema (r1)}} db2 close finish_test |
Changes to test/dbfuzz001.test.
︙ | ︙ | |||
301 302 303 304 305 306 307 | | 320: 41 54 45 20 49 4e 44 45 58 20 74 33 78 20 4f 4e ATE INDEX t3x ON | 336: 20 74 33 28 78 29 2e 04 06 17 15 11 01 45 69 6e t3(x).......Ein | 352: 64 65 78 74 32 63 64 74 32 05 43 52 45 41 54 45 dext2cdt2.CREATE | 368: 20 49 4e 44 45 58 20 74 32 63 64 20 4f 4e 20 74 INDEX t2cd ON t | 384: 32 28 63 2c 64 29 28 05 06 17 11 11 01 3d 74 61 2(c,d)(......=ta | 400: 62 6c 65 74 33 74 33 07 43 52 45 41 54 45 20 54 blet3t3.CREATE T | 416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29 ABLE t3(c,x,e,f) | | | 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | | 320: 41 54 45 20 49 4e 44 45 58 20 74 33 78 20 4f 4e ATE INDEX t3x ON | 336: 20 74 33 28 78 29 2e 04 06 17 15 11 01 45 69 6e t3(x).......Ein | 352: 64 65 78 74 32 63 64 74 32 05 43 52 45 41 54 45 dext2cdt2.CREATE | 368: 20 49 4e 44 45 58 20 74 32 63 64 20 4f 4e 20 74 INDEX t2cd ON t | 384: 32 28 63 2c 64 29 28 05 06 17 11 11 01 3d 74 61 2(c,d)(......=ta | 400: 62 6c 65 74 33 74 33 07 43 52 45 41 54 45 20 54 blet3t3.CREATE T | 416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29 ABLE t3(c,x,e,f) | 432: 28 02 06 17 11 11 01 3d 74 61 62 6c 65 74 32 74 (......=tablet2t | 448: 32 32 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 22CREATE TABLE t | 464: 32 28 63 2c 64 2c 65 2c 66 29 24 01 06 17 11 11 2(c,d,e,f)$..... | 480: 01 35 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 .5tablet1t1.CREA | 496: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 29 TE TABLE t1(a,b) | page 2 offset 512 | 0: 0d 00 00 00 04 01 cf 00 01 fa 01 f3 01 de 01 cf ................ | 160: 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 .. ............. |
︙ | ︙ |
Changes to test/dbfuzz2.c.
︙ | ︙ | |||
207 208 209 210 211 212 213 214 215 216 217 218 219 220 | #endif if( bVdbeDebug ){ sqlite3_exec(db, "PRAGMA vdbe_debug=ON", 0, 0, 0); } if( mxCb>0 ){ sqlite3_progress_handler(db, 10, progress_handler, 0); } for(i=0; i<sizeof(azSql)/sizeof(azSql[0]); i++){ if( eVerbosity>=1 ){ printf("%s\n", azSql[i]); fflush(stdout); } zErr = 0; nCb = 0; | > > > | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | #endif if( bVdbeDebug ){ sqlite3_exec(db, "PRAGMA vdbe_debug=ON", 0, 0, 0); } if( mxCb>0 ){ sqlite3_progress_handler(db, 10, progress_handler, 0); } #ifdef SQLITE_TESTCTRL_PRNG_SEED sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, 1, db); #endif for(i=0; i<sizeof(azSql)/sizeof(azSql[0]); i++){ if( eVerbosity>=1 ){ printf("%s\n", azSql[i]); fflush(stdout); } zErr = 0; nCb = 0; |
︙ | ︙ |
Changes to test/dbstatus.test.
︙ | ︙ | |||
59 60 61 62 63 64 65 | proc lookaside {db} { expr { $::lookaside_buffer_size * [lindex [sqlite3_db_status $db SQLITE_DBSTATUS_LOOKASIDE_USED 0] 1] } } | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | proc lookaside {db} { expr { $::lookaside_buffer_size * [lindex [sqlite3_db_status $db SQLITE_DBSTATUS_LOOKASIDE_USED 0] 1] } } ifcapable stat4 { set STAT3 1 } else { set STAT3 0 } #--------------------------------------------------------------------------- # Run the dbstatus-2 and dbstatus-3 tests with several of different |
︙ | ︙ |
Changes to test/distinct2.test.
︙ | ︙ | |||
225 226 227 228 229 230 231 232 233 | CREATE TABLE t2(x PRIMARY KEY); INSERT INTO t2 VALUES('yes'); SELECT DISTINCT a FROM t1, t2 WHERE x=b; ANALYZE; SELECT DISTINCT a FROM t1, t2 WHERE x=b; } {1 1} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | CREATE TABLE t2(x PRIMARY KEY); INSERT INTO t2 VALUES('yes'); SELECT DISTINCT a FROM t1, t2 WHERE x=b; ANALYZE; SELECT DISTINCT a FROM t1, t2 WHERE x=b; } {1 1} #------------------------------------------------------------------------- reset_db do_execsql_test 2000 { CREATE TABLE t0 (c0, c1, c2, PRIMARY KEY (c0, c1)); CREATE TABLE t1 (c2); INSERT INTO t0(c2) VALUES (0),(1),(3),(4),(5),(6),(7),(8),(9),(10),(11); INSERT INTO t0(c1) VALUES ('a'); INSERT INTO t1(c2) VALUES (0); } do_execsql_test 2010 { SELECT DISTINCT t0.c0, t1._rowid_, t0.c1 FROM t1 CROSS JOIN t0 ORDER BY t0.c0; } {{} 1 {} {} 1 a} do_execsql_test 1.2 { ANALYZE; } do_execsql_test 2020 { SELECT DISTINCT t0.c0, t1._rowid_, t0.c1 FROM t1 CROSS JOIN t0 ORDER BY t0.c0; } {{} 1 {} {} 1 a} do_execsql_test 2030 { CREATE TABLE t2(a, b, c); CREATE INDEX t2ab ON t2(a, b); WITH c(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM c WHERE i<64) INSERT INTO t2 SELECT 'one', i%2, 'one' FROM c; WITH c(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM c WHERE i<64) INSERT INTO t2 SELECT 'two', i%2, 'two' FROM c; CREATE TABLE t3(x INTEGER PRIMARY KEY); INSERT INTO t3 VALUES(1); ANALYZE; } do_execsql_test 2040 { SELECT DISTINCT a, b, x FROM t3 CROSS JOIN t2 ORDER BY a; } { one 0 1 one 1 1 two 0 1 two 1 1 } #------------------------------------------------------------------------- # reset_db do_execsql_test 3000 { CREATE TABLE t0 (c0, c1 NOT NULL DEFAULT 1, c2, PRIMARY KEY (c0, c1)); INSERT INTO t0(c2) VALUES (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL); INSERT INTO t0(c2) VALUES('a'); } do_execsql_test 3010 { SELECT DISTINCT * FROM t0 WHERE NULL IS t0.c0; } { {} 1 {} {} 1 a } do_execsql_test 3020 { ANALYZE; } do_execsql_test 3030 { SELECT DISTINCT * FROM t0 WHERE NULL IS c0; } { {} 1 {} {} 1 a } finish_test |
Added test/filter1.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | # 2018 May 8 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix filter1 ifcapable !windowfunc { finish_test return } do_execsql_test 1.0 { CREATE TABLE t1(a); CREATE INDEX i1 ON t1(a); INSERT INTO t1 VALUES(1), (2), (3), (4), (5), (6), (7), (8), (9); } do_execsql_test 1.1 { SELECT sum(a) FROM t1; } 45 do_execsql_test 1.2 { SELECT sum(a) FILTER( WHERE a<5 ) FROM t1; } 10 do_execsql_test 1.3 { SELECT sum(a) FILTER( WHERE a>9 ), sum(a) FILTER( WHERE a>8 ), sum(a) FILTER( WHERE a>7 ), sum(a) FILTER( WHERE a>6 ), sum(a) FILTER( WHERE a>5 ), sum(a) FILTER( WHERE a>4 ), sum(a) FILTER( WHERE a>3 ), sum(a) FILTER( WHERE a>2 ), sum(a) FILTER( WHERE a>1 ), sum(a) FILTER( WHERE a>0 ) FROM t1; } {{} 9 17 24 30 35 39 42 44 45} do_execsql_test 1.4 { SELECT max(a) FILTER (WHERE (a % 2)==0) FROM t1 } {8} do_execsql_test 1.5 { SELECT min(a) FILTER (WHERE a>4) FROM t1 } {5} do_execsql_test 1.6 { SELECT count(*) FILTER (WHERE a!=5) FROM t1 } {8} do_execsql_test 1.7 { SELECT min(a) FILTER (WHERE a>3) FROM t1 GROUP BY (a%2) ORDER BY 1; } {4 5} do_execsql_test 1.8 { CREATE VIEW vv AS SELECT sum(a) FILTER( WHERE a>9 ), sum(a) FILTER( WHERE a>8 ), sum(a) FILTER( WHERE a>7 ), sum(a) FILTER( WHERE a>6 ), sum(a) FILTER( WHERE a>5 ), sum(a) FILTER( WHERE a>4 ), sum(a) FILTER( WHERE a>3 ), sum(a) FILTER( WHERE a>2 ), sum(a) FILTER( WHERE a>1 ), sum(a) FILTER( WHERE a>0 ) FROM t1; SELECT * FROM vv; } {{} 9 17 24 30 35 39 42 44 45} #------------------------------------------------------------------------- # Test some errors: # # .1 FILTER on a non-aggregate function, # .2 Window function in FILTER clause, # .3 Aggregate function in FILTER clause, # reset_db do_execsql_test 2.0 { CREATE TABLE t1(a); INSERT INTO t1 VALUES(1), (2), (3), (4), (5), (6), (7), (8), (9); } do_catchsql_test 2.1 { SELECT upper(a) FILTER (WHERE a=1) FROM t1 } {1 {FILTER may not be used with non-aggregate upper()}} do_catchsql_test 2.2 { SELECT sum(a) FILTER (WHERE 1 - max(a) OVER () > 0) FROM t1 } {1 {misuse of window function max()}} do_catchsql_test 2.3 { SELECT sum(a) FILTER (WHERE 1 - count(a)) FROM t1 } {1 {misuse of aggregate function count()}} finish_test |
Added test/filter2.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | # 2018 May 19 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # source [file join [file dirname $argv0] pg_common.tcl] #========================================================================= start_test filter2 "2019 July 2" ifcapable !windowfunc execsql_test 1.0 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER); INSERT INTO t1 VALUES (1, 7), (2, 3), (3, 5), (4, 30), (5, 26), (6, 23), (7, 27), (8, 3), (9, 17), (10, 26), (11, 33), (12, 25), (13, NULL), (14, 47), (15, 36), (16, 13), (17, 45), (18, 31), (19, 11), (20, 36), (21, 37), (22, 21), (23, 22), (24, 14), (25, 16), (26, 3), (27, 7), (28, 29), (29, 50), (30, 38), (31, 3), (32, 36), (33, 12), (34, 4), (35, 46), (36, 3), (37, 48), (38, 23), (39, NULL), (40, 24), (41, 5), (42, 46), (43, 11), (44, NULL), (45, 18), (46, 25), (47, 15), (48, 18), (49, 23); } execsql_test 1.1 { SELECT sum(b) FROM t1 } execsql_test 1.2 { SELECT sum(b) FILTER (WHERE a<10) FROM t1 } execsql_test 1.3 { SELECT count(DISTINCT b) FROM t1 } execsql_test 1.4 { SELECT count(DISTINCT b) FILTER (WHERE a!=19) FROM t1 } execsql_test 1.5 { SELECT min(b) FILTER (WHERE a>19), min(b) FILTER (WHERE a>0), max(a+b) FILTER (WHERE a>19), max(b+a) FILTER (WHERE a BETWEEN 10 AND 40) FROM t1; } execsql_test 1.6 { SELECT min(b), min(b), max(a+b), max(b+a) FROM t1 GROUP BY (a%10) ORDER BY 1, 2, 3, 4; } execsql_test 1.7 { SELECT min(b) FILTER (WHERE a>19), min(b) FILTER (WHERE a>0), max(a+b) FILTER (WHERE a>19), max(b+a) FILTER (WHERE a BETWEEN 10 AND 40) FROM t1 GROUP BY (a%10) ORDER BY 1, 2, 3, 4; } execsql_test 1.8 { SELECT sum(a+b) FILTER (WHERE a=NULL) FROM t1 } execsql_test 1.9 { SELECT (a%5) FROM t1 GROUP BY (a%5) HAVING sum(b) FILTER (WHERE b<20) > 34 ORDER BY 1 } execsql_test 1.10 { SELECT (a%5), sum(b) FILTER (WHERE b<20) AS bbb FROM t1 GROUP BY (a%5) HAVING sum(b) FILTER (WHERE b<20) >34 ORDER BY 1 } execsql_test 1.11 { SELECT (a%5), sum(b) FILTER (WHERE b<20) AS bbb FROM t1 GROUP BY (a%5) HAVING sum(b) FILTER (WHERE b<20) >34 ORDER BY 2 } execsql_test 1.12 { SELECT (a%5), sum(b) FILTER (WHERE b<20) AS bbb, count(distinct b) FILTER (WHERE b<20 OR a=13) AS ccc FROM t1 GROUP BY (a%5) ORDER BY 2 } execsql_test 1.13 { SELECT string_agg(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=0), string_agg(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=1), count(*) FILTER (WHERE b%2!=0), count(*) FILTER (WHERE b%2!=1) FROM t1; } execsql_float_test 1.14 { SELECT avg(b) FILTER (WHERE b>a), avg(b) FILTER (WHERE b<a) FROM t1 GROUP BY (a%2) ORDER BY 1,2; } execsql_test 1.15 { SELECT a/5, sum(b) FILTER (WHERE a%5=0), sum(b) FILTER (WHERE a%5=1), sum(b) FILTER (WHERE a%5=2), sum(b) FILTER (WHERE a%5=3), sum(b) FILTER (WHERE a%5=4) FROM t1 GROUP BY (a/5) ORDER BY 1; } finish_test |
Added test/filter2.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | # 2019 July 2 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # #################################################### # DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED! #################################################### set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix filter2 ifcapable !windowfunc { finish_test ; return } do_execsql_test 1.0 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER); INSERT INTO t1 VALUES (1, 7), (2, 3), (3, 5), (4, 30), (5, 26), (6, 23), (7, 27), (8, 3), (9, 17), (10, 26), (11, 33), (12, 25), (13, NULL), (14, 47), (15, 36), (16, 13), (17, 45), (18, 31), (19, 11), (20, 36), (21, 37), (22, 21), (23, 22), (24, 14), (25, 16), (26, 3), (27, 7), (28, 29), (29, 50), (30, 38), (31, 3), (32, 36), (33, 12), (34, 4), (35, 46), (36, 3), (37, 48), (38, 23), (39, NULL), (40, 24), (41, 5), (42, 46), (43, 11), (44, NULL), (45, 18), (46, 25), (47, 15), (48, 18), (49, 23); } {} do_execsql_test 1.1 { SELECT sum(b) FROM t1 } {1041} do_execsql_test 1.2 { SELECT sum(b) FILTER (WHERE a<10) FROM t1 } {141} do_execsql_test 1.3 { SELECT count(DISTINCT b) FROM t1 } {31} do_execsql_test 1.4 { SELECT count(DISTINCT b) FILTER (WHERE a!=19) FROM t1 } {31} do_execsql_test 1.5 { SELECT min(b) FILTER (WHERE a>19), min(b) FILTER (WHERE a>0), max(a+b) FILTER (WHERE a>19), max(b+a) FILTER (WHERE a BETWEEN 10 AND 40) FROM t1; } {3 3 88 85} do_execsql_test 1.6 { SELECT min(b), min(b), max(a+b), max(b+a) FROM t1 GROUP BY (a%10) ORDER BY 1, 2, 3, 4; } {3 3 58 58 3 3 66 66 3 3 71 71 3 3 88 88 4 4 61 61 5 5 54 54 7 7 85 85 11 11 79 79 16 16 81 81 24 24 68 68} do_execsql_test 1.7 { SELECT min(b) FILTER (WHERE a>19), min(b) FILTER (WHERE a>0), max(a+b) FILTER (WHERE a>19), max(b+a) FILTER (WHERE a BETWEEN 10 AND 40) FROM t1 GROUP BY (a%10) ORDER BY 1, 2, 3, 4; } {3 3 58 58 3 3 71 39 4 4 38 61 7 7 85 85 11 5 54 45 16 16 81 81 18 3 66 61 21 3 88 68 23 11 79 79 24 24 68 68} do_execsql_test 1.8 { SELECT sum(a+b) FILTER (WHERE a=NULL) FROM t1 } {{}} do_execsql_test 1.9 { SELECT (a%5) FROM t1 GROUP BY (a%5) HAVING sum(b) FILTER (WHERE b<20) > 34 ORDER BY 1 } {3 4} do_execsql_test 1.10 { SELECT (a%5), sum(b) FILTER (WHERE b<20) AS bbb FROM t1 GROUP BY (a%5) HAVING sum(b) FILTER (WHERE b<20) >34 ORDER BY 1 } {3 49 4 46} do_execsql_test 1.11 { SELECT (a%5), sum(b) FILTER (WHERE b<20) AS bbb FROM t1 GROUP BY (a%5) HAVING sum(b) FILTER (WHERE b<20) >34 ORDER BY 2 } {4 46 3 49} do_execsql_test 1.12 { SELECT (a%5), sum(b) FILTER (WHERE b<20) AS bbb, count(distinct b) FILTER (WHERE b<20 OR a=13) AS ccc FROM t1 GROUP BY (a%5) ORDER BY 2 } {2 25 3 0 34 2 1 34 4 4 46 4 3 49 5} do_execsql_test 1.13 { SELECT group_concat(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=0), group_concat(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=1), count(*) FILTER (WHERE b%2!=0), count(*) FILTER (WHERE b%2!=1) FROM t1; } {7_3_5_23_27_3_17_33_25_47_13_45_31_11_37_21_3_7_29_3_3_23_5_11_25_15_23 30_26_26_36_36_22_14_16_50_38_36_12_4_46_48_24_46_18_18 27 19} do_test 1.14 { set myres {} foreach r [db eval {SELECT avg(b) FILTER (WHERE b>a), avg(b) FILTER (WHERE b<a) FROM t1 GROUP BY (a%2) ORDER BY 1,2;}] { lappend myres [format %.4f [set r]] } set res2 {30.8333 13.7273 31.4167 13.0000} set i 0 foreach r [set myres] r2 [set res2] { if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { error "list element [set i] does not match: got=[set r] expected=[set r2]" } incr i } set {} {} } {} do_execsql_test 1.15 { SELECT a/5, sum(b) FILTER (WHERE a%5=0), sum(b) FILTER (WHERE a%5=1), sum(b) FILTER (WHERE a%5=2), sum(b) FILTER (WHERE a%5=3), sum(b) FILTER (WHERE a%5=4) FROM t1 GROUP BY (a/5) ORDER BY 1; } {0 {} 7 3 5 30 1 26 23 27 3 17 2 26 33 25 {} 47 3 36 13 45 31 11 4 36 37 21 22 14 5 16 3 7 29 50 6 38 3 36 12 4 7 46 3 48 23 {} 8 24 5 46 11 {} 9 18 25 15 18 23} finish_test |
Added test/filterfault.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | # 2018 May 8 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix filterfault ifcapable !windowfunc { finish_test return } do_execsql_test 1.0 { CREATE TABLE t1(a, b, c, d); INSERT INTO t1 VALUES(1, 2, 3, 4); INSERT INTO t1 VALUES(5, 6, 7, 8); INSERT INTO t1 VALUES(9, 10, 11, 12); } faultsim_save_and_close do_faultsim_test 1 -faults oom-t* -prep { faultsim_restore_and_reopen } -body { execsql { SELECT sum(a) FILTER (WHERE b<5), count() FILTER (WHERE d!=c) FROM t1 GROUP BY c ORDER BY 1; } } -test { faultsim_test_result {0 {{} 1 {} 1 1 1}} } finish_test |
Changes to test/fkey8.test.
︙ | ︙ | |||
225 226 227 228 229 230 231 | COMMIT; } do_execsql_test 5.3 { PRAGMA integrity_check; } {ok} finish_test | < | 225 226 227 228 229 230 231 | COMMIT; } do_execsql_test 5.3 { PRAGMA integrity_check; } {ok} finish_test |
Changes to test/fts3corrupt4.test.
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # If SQLITE_ENABLE_FTS3 is defined, omit this file. ifcapable !fts3 { finish_test return } sqlite3_fts3_may_be_corrupt 1 do_execsql_test 1.0 { BEGIN; CREATE VIRTUAL TABLE ft USING fts3; INSERT INTO ft VALUES('aback'); INSERT INTO ft VALUES('abaft'); INSERT INTO ft VALUES('abandon'); | > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | # If SQLITE_ENABLE_FTS3 is defined, omit this file. ifcapable !fts3 { finish_test return } sqlite3_fts3_may_be_corrupt 1 database_may_be_corrupt do_execsql_test 1.0 { BEGIN; CREATE VIRTUAL TABLE ft USING fts3; INSERT INTO ft VALUES('aback'); INSERT INTO ft VALUES('abaft'); INSERT INTO ft VALUES('abandon'); |
︙ | ︙ | |||
2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 | | page 7 offset 24576 | 0: 0d 00 00 00 01 0f f7 00 0f f7 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 00 00 00 07 00 03 00 14 08 45 b5 03 .............E.. | end crash-f7b636a855e1d2.db }]} {} do_execsql_test 14.1 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10) INSERT INTO t1(a) SELECT randomblob(3000) FROM c; } do_catchsql_test 14.2 { INSERT INTO t1(t1) VALUES('optimize'); } {1 {database disk image is malformed}} | > | 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 | | page 7 offset 24576 | 0: 0d 00 00 00 01 0f f7 00 0f f7 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 00 00 00 07 00 03 00 14 08 45 b5 03 .............E.. | end crash-f7b636a855e1d2.db }]} {} do_execsql_test 14.1 { PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10) INSERT INTO t1(a) SELECT randomblob(3000) FROM c; } do_catchsql_test 14.2 { INSERT INTO t1(t1) VALUES('optimize'); } {1 {database disk image is malformed}} |
︙ | ︙ | |||
3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 | | 4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72 =100,8...+integr | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 uild....optimize | end crash-526ea445f41c02.db }]} {} do_catchsql_test 19.1 { SELECT rowid,a,c,snippet(t1,85101090932165,-1,10) FROM t1 WHERE a MATCH 'rtree'; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 20.0 { sqlite3 db {} | > | 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 | | 4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72 =100,8...+integr | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 uild....optimize | end crash-526ea445f41c02.db }]} {} do_catchsql_test 19.1 { PRAGMA writable_schema = 1; SELECT rowid,a,c,snippet(t1,85101090932165,-1,10) FROM t1 WHERE a MATCH 'rtree'; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 20.0 { sqlite3 db {} |
︙ | ︙ | |||
3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 | | page 7 offset 24576 | 0: 0d 00 00 00 01 0f f7 00 0f f7 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 00 00 00 07 00 03 00 14 08 45 b5 03 .............E.. | end crash-afecd03c862e58.db }]} {} do_execsql_test 20.1 { BEGIN; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10) INSERT INTO t1(a) SELECT randomblob(3000) FROM c; } do_execsql_test 20.2 { INSERT INTO t1(t1) VALUES('optimize'); | > | 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 | | page 7 offset 24576 | 0: 0d 00 00 00 01 0f f7 00 0f f7 00 00 00 00 00 00 ................ | 4080: 00 00 00 00 00 00 00 07 00 03 00 14 08 45 b5 03 .............E.. | end crash-afecd03c862e58.db }]} {} do_execsql_test 20.1 { PRAGMA writable_schema = 1; BEGIN; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10) INSERT INTO t1(a) SELECT randomblob(3000) FROM c; } do_execsql_test 20.2 { INSERT INTO t1(t1) VALUES('optimize'); |
︙ | ︙ | |||
3467 3468 3469 3470 3471 3472 3473 | | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72 =100,8...+integr | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | 4080: 75 69 6c 64 0a 01 02 1d 00 00 00 00 00 00 00 00 uild............ | end crash-18cc014e42e828.db }]} {} | < > | 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 | | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72 =100,8...+integr | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | 4080: 75 69 6c 64 0a 01 02 1d 00 00 00 00 00 00 00 00 uild............ | end crash-18cc014e42e828.db }]} {} do_catchsql_test 21.1 { PRAGMA writable_schema = 1; SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'R*'; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 22.0 { sqlite3 db {} |
︙ | ︙ | |||
3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 | | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72 =100,8...+integr | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | end crash-b794c89d922ac9.db }]} {} do_catchsql_test 22.1 { SELECT snippet(t1,'', '', '--',-1,01)==0 FROM t1 WHERE a MATCH 'rtree OR json1rtree OR json1'; } {0 {0 0 0 0 0 0 0}} #------------------------------------------------------------------------- reset_db do_test 23.0 { | > | 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 | | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72 =100,8...+integr | 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb | end crash-b794c89d922ac9.db }]} {} do_catchsql_test 22.1 { PRAGMA writable_schema = 1; SELECT snippet(t1,'', '', '--',-1,01)==0 FROM t1 WHERE a MATCH 'rtree OR json1rtree OR json1'; } {0 {0 0 0 0 0 0 0}} #------------------------------------------------------------------------- reset_db do_test 23.0 { |
︙ | ︙ | |||
3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 | | 4032: 6d 65 71 97 65 3d 35 0d 04 02 23 6d 65 72 67 65 meq.e=5...#merge | 4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72 =100,8...+integr | 4064: 69 74 79 00 00 00 00 00 00 00 00 00 00 00 00 00 ity............. | end crash-670b15f2955a36.db }]} {} do_catchsql_test 23.1 { SELECT 'FyzLy'FROM t1 WHERE t1 MATCH 'j'; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 24.0 { sqlite3 db {} | > | 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 | | 4032: 6d 65 71 97 65 3d 35 0d 04 02 23 6d 65 72 67 65 meq.e=5...#merge | 4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72 =100,8...+integr | 4064: 69 74 79 00 00 00 00 00 00 00 00 00 00 00 00 00 ity............. | end crash-670b15f2955a36.db }]} {} do_catchsql_test 23.1 { PRAGMA writable_schema = 1; SELECT 'FyzLy'FROM t1 WHERE t1 MATCH 'j'; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 24.0 { sqlite3 db {} |
︙ | ︙ | |||
4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 | | 4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f ...........#auto | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =1.............. | end crash-369d042958c29b.db }]} {} do_catchsql_test 24.1 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT '4hE'+x FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; } {0 {}} do_catchsql_test 24.2 { UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h'; } {0 {}} | > | 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 | | 4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f ...........#auto | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =1.............. | end crash-369d042958c29b.db }]} {} do_catchsql_test 24.1 { PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT '4hE'+x FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; } {0 {}} do_catchsql_test 24.2 { UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h'; } {0 {}} |
︙ | ︙ | |||
4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 | | 4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f ...........#auto | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =1.............. | end crash-dde9e76ed8ab2d.db }]} {} do_catchsql_test 25.1 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x%1 FROM c WHERE x<599237) INSERT INTO t1( a ) SELECT randomblob(3000) FROM t2 ; } {0 {}} do_catchsql_test 25.2 { UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h*'; } {0 {}} | > | 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 | | 4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f ...........#auto | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =1.............. | end crash-dde9e76ed8ab2d.db }]} {} do_catchsql_test 25.1 { PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x%1 FROM c WHERE x<599237) INSERT INTO t1( a ) SELECT randomblob(3000) FROM t2 ; } {0 {}} do_catchsql_test 25.2 { UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h*'; } {0 {}} |
︙ | ︙ | |||
4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 | | page 7 offset 24576 | 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 00 00 00 ...........#a... | end crash-26682721375870.db }]} {} do_execsql_test 26.1 { SELECT count(*) FROM ( SELECT t1, (t1) FROM t1 WHERE b MATCH 'x' ) } 34 #------------------------------------------------------------------------- reset_db | > | 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 | | page 7 offset 24576 | 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 00 00 00 ...........#a... | end crash-26682721375870.db }]} {} do_execsql_test 26.1 { PRAGMA writable_schema = 1; SELECT count(*) FROM ( SELECT t1, (t1) FROM t1 WHERE b MATCH 'x' ) } 34 #------------------------------------------------------------------------- reset_db |
︙ | ︙ | |||
4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 | | 4016: 00 00 00 00 00 00 00 00 0f 85 02 23 61 75 74 6f ...........#auto | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =1.............. | end crash-23ddd777a03bfd.db }]} {} do_catchsql_test 27.2 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x GLOB 2.16770 FROM x) INSERT INTO t1(a) SELECT randomblob(3000) FROM t2 ; } {0 {}} do_catchsql_test 27.3 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<2.653) INSERT INTO t1(a) SELECT randomblob(-current_time) FROM c; } {0 {}} | > | 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 | | 4016: 00 00 00 00 00 00 00 00 0f 85 02 23 61 75 74 6f ...........#auto | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =1.............. | end crash-23ddd777a03bfd.db }]} {} do_catchsql_test 27.2 { PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x GLOB 2.16770 FROM x) INSERT INTO t1(a) SELECT randomblob(3000) FROM t2 ; } {0 {}} do_catchsql_test 27.3 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<2.653) INSERT INTO t1(a) SELECT randomblob(-current_time) FROM c; } {0 {}} |
︙ | ︙ | |||
5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 | | 4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f ...........#auto | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =1.............. | end crash-159ac1ca51ed55.db }]} {} do_catchsql_test 28.1 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; } {0 {}} do_catchsql_test 28.1 { UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h'; } {0 {}} | > | 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 | | 4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f ...........#auto | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =1.............. | end crash-159ac1ca51ed55.db }]} {} do_catchsql_test 28.1 { PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; } {0 {}} do_catchsql_test 28.1 { UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h'; } {0 {}} |
︙ | ︙ | |||
5090 5091 5092 5093 5094 5095 5096 | INSERT INTO t1(a) SELECT randomblob(2829) FROM c; } {0 {}} do_catchsql_test 28.1 { INSERT INTO t1(t1) SELECT x FROM t2; } {0 {}} | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 | INSERT INTO t1(a) SELECT randomblob(2829) FROM c; } {0 {}} do_catchsql_test 28.1 { INSERT INTO t1(t1) SELECT x FROM t2; } {0 {}} #------------------------------------------------------------------------- # reset_db do_test 29.0 { sqlite3 db {} db deserialize [decode_hexdb { .open --hexdb | size 28672 pagesize 4096 filename crash-53f41622dd3bf6.db | page 1 offset 0 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ | 96: 00 00 00 00 0d 0e b1 00 06 0d a4 00 0f 8d 0f 21 ...............! | 112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00 .....~.......... | 3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c ...........1tabl | 3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42 et2t2.CREATE TAB | 3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01 LE t2(x).3...... | 3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 54 69 72 .5tablet1_segTir | 3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45 t1_segdir.CREATE | 3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69 TABLE 't1_segdi | 3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52 r'(level INTEGER | 3600: 2c 69 64 78 20 49 4d 54 45 47 45 52 2c 73 74 61 ,idx IMTEGER,sta | 3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52 rt_block INTEGER | 3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 ,leaves_end_bloc | 3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c k INTEGER,end_bl | 3664: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f 6f 74 ock INTEGER,root | 3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45 BLOB,PRIMARY KE | 3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06 Y(level, idx))1. | 3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74 ..E...indexsqlit | 3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73 e_autoindex_t1_s | 3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72 egdir_1t1_segdir | 3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01 .........f...##. | 3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e ..tablet1_segmen | 3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52 tst1_segments.CR | 3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 EATE TABLE 't1_s | 3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64 egments'(blockid | 3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY | 3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 KEY, block BLOB | 3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74 )j...!!...tablet | 3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont | 3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE | 3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f 't1_content'(do | 3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 39 4d cid INTEGER PR9M | 3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20 ARY KEY, 'c0a', | 3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 12 06 'c1b', 'c2c')8.. | 3984: 17 11 11 08 5f 74 61 6b 3c 65 74 31 74 31 43 52 ...._tak<et1t1CR | 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB | 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 33 LE t1 USING fts3 | 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... | page 3 offset 8192 | 0: 0d 00 00 00 25 0b 48 00 0f d8 0f af 0f 86 0f 74 ....%.H........t | 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./.......... | 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$...... | 48: 0d bb 0d a0 0d 84 03 28 0d 4f 0d 35 0d 1b 0c fb .......(.O.5.... | 64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a .......x.W.>.$.. | 80: 0b 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .H.............. | 2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 72 7f 00 .........?%..r.. | 2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e .COMPILER=gcc-5. | 2912: 34 2e 30 20 32 30 31 36 30 36 30 39 21 44 45 42 4.0 20160609!DEB | 2928: 55 47 20 45 4e 41 42 4c 45 20 44 42 53 54 41 54 UG ENABLE DBSTAT | 2944: 20 56 54 41 42 20 45 4e 41 42 4c 46 20 46 54 53 VTAB ENABLF FTS | 2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e 4 ENABLE FTS5 EN | 2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41 ABLE GEOPOLY ENA | 2992: 42 4c 55 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45 BLU JSON1 ENABLE | 3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20 MEMSYS5 ENABLE | 3024: 52 54 52 45 45 56 4d 41 58 20 4d 45 4d 4f 52 59 RTREEVMAX MEMORY | 3040: 3d 35 30 30 30 30 30 30 30 20 4f 4d 49 54 20 4c =50000000 OMIT L | 3056: 4f 42 43 20 45 58 54 45 4e 53 49 4f 4e 20 54 48 OBC EXTENSION TH | 3072: 52 45 41 44 53 41 46 45 3d 40 18 24 05 00 25 0f READSAFE=@.$..%. | 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI | 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA | 3120: 44 53 41 46 45 3d 31 58 4e 4f 43 41 53 45 17 22 DSAFE=1XNOCASE.. | 3136: 05 00 25 0f 17 54 48 52 45 41 44 43 41 46 45 3d ..%..THREADCAFE= | 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM | 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO | 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O | 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 48 MIT LOAD EXTENSH | 3216: cf 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 .NXNOCASE....3.. | 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS | 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3.. | 3264: 4d 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30 30 30 MAX MEMORY-50000 | 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3. | 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 | 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3 | 3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MAX MEMORY=500 | 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% | 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB | 3376: 49 4e 41 52 49 18 1a 05 0d a5 0f 19 45 4e 41 42 INARI.......ENAB | 3392: 4c 45 20 52 54 52 45 45 58 4e 4f be 31 53 45 17 LE RTREEXNO.1SE. | 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 51 ...%..ENABLE RTQ | 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E | 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI | 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL | 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE | 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME | 3504: 4d 53 59 53 37 f8 52 54 52 49 4d 18 14 05 00 25 MSYS7.RTRIM....% | 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB | 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB | 3552: 4c 45 20 4a 53 4f 3e 31 58 4e 4f 43 41 53 45 17 LE JSO>1XNOCASE. | 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO | 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E | 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI | 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL | 3632: 48 c0 47 45 4f 50 4f 4c 40 58 4e 4f 43 41 53 45 H.GEOPOL@XNOCASE | 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE | 3664: 4f 50 4f 4c 59 58 52 54 51 49 4d 17 0f 05 00 23 OPOLYXRTQIM....# | 3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI | 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL | 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E FTS5XNOCASE... | 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X | 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB | 3760: 4c 45 20 46 54 53 34 58 42 49 4d 41 52 59 17 0b LE FTS4XBIMARY.. | 3776: 05 00 23 0f 19 45 4e 31 42 4c 45 20 46 1a 53 34 ..#..EN1BLE F.S4 | 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN | 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM. | 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS | 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. | 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS | 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE. | 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS | 3904: 54 96 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 T.T VTABXRTRIM.. | 3920: 05 00 17 0f 1e e4 45 42 55 47 58 42 49 4e 41 52 ......EBUGXBINAR | 3936: 59 11 05 05 00 17 0e 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO | 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG | 3968: 58 52 54 52 49 4d 27 03 05 01 43 0f 19 43 4f 4d XRTRIM'...C..COM | 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 | 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY' | 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g | 4032: 63 63 2d 35 2e 34 2e 30 40 32 30 31 36 30 36 30 cc-5.4.0@2016060 | 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C | 4064: 4f 4d 4f 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMOILER=gcc-5.4. | 4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d 0 20160609XRTRIM | page 4 offset 12288 | 0: 0d 00 00 01 00 10 00 00 00 00 00 00 00 00 00 00 ................ | page 5 offset 16384 | 0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00 ................ | 2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33 ...........0 253 | 2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36 ..0.%.....201606 | 3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35 09.%....4.%....5 | 3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a .%....0000000.%. | 3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00 ...compiler.%... | 3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75 .dbstat.%....ebu | 3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09 g.%....enable.%. | 3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f .........xtensio | 3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03 n.%....fts4.%... | 3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01 .5.%....gcc.%... | 3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f .eopoly.%....jso | 3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00 n1.%....load.%.. | 3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6d 6f 72 79 ..max.%....emory | 3184: 03 25 19 00 03 04 73 79 73 4d 03 25 15 00 00 04 .%....sysM.%.... | 3200: 6e 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03 nmit.%....rtree. | 3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03 %....threadsafe. | 3232: 25 0e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01 %....vtab.%...P. | 3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30 ........0 835..0 | 3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 00 ................ | 3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 bd .....20160609... | 3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05 .........4...... | 3312: 00 01 06 00 00 01 35 09 01 04 00 01 04 00 02 04 ......5......... | 3328: 00 01 07 30 30 e6 30 30 30 30 09 1c 04 00 01 04 ...00.0000...... | 3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02 ......binary<... | 3360: 02 00 03 01 02 02 00 04 01 02 02 10 03 01 02 02 ................ | 3376: 00 0f 71 02 12 00 03 01 02 02 00 03 01 65 02 00 ..q..........e.. | 3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 ................ | 3408: 01 0d a2 00 03 01 02 02 00 00 08 63 3b 6d 70 69 ...........c;mpi | 3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 64 ler............d | 3440: 62 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01 bstat........... | 3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00 .ebug........... | 3472: 06 65 6e 61 62 6c 65 3f 07 02 00 01 02 00 01 02 .enable?........ | 3488: 00 01 02 00 01 02 00 01 01 f0 01 02 00 01 02 00 ................ | 3504: 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 ................ | 3520: 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 ................ | 3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f .........xtensio | 3552: 6e 09 1f 04 00 01 04 00 01 04 00 00 04 66 74 73 n............fts | 3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d 4............5.. | 3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03 ..........gcc... | 3600: 00 01 03 00 01 03 00 01 06 65 6f 70 6f 6c 79 09 .........eopoly. | 3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31 ...........json1 | 3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64 ............load | 3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09 ............max. | 3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79 ...........emory | 3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35 ............sys5 | 3696: 09 16 03 00 01 03 00 01 03 00 00 06 6e 6f 63 61 ............noca | 3712: 73 65 3c 02 01 02 02 00 03 01 02 02 00 03 01 02 se<............. | 3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ | 3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 01 f0 ................ | 3760: 03 01 02 02 05 93 01 02 02 00 03 01 02 02 00 00 ................ | 3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00 .omit........... | 3792: 05 72 8a 72 65 65 09 19 03 00 01 03 00 11 03 00 .r.ree.......... | 3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03 ..im<........... | 3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 ................ | 3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 ................ | 3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ | 3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02 ...threadsafe... | 3888: 00 01 02 00 01 02 00 00 04 76 75 61 62 09 07 04 .........vuab... | 3904: 00 01 04 00 01 04 00 00 61 78 b4 01 01 01 01 02 ........ax...... | 3920: 00 01 01 01 02 00 00 f1 01 02 00 01 01 01 02 00 ................ | 3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 ................ | 3952: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 ................ | 3968: 01 02 00 01 01 01 01 ff 01 01 01 02 00 01 01 01 ................ | 3984: 02 00 01 01 01 02 00 01 01 01 02 09 01 01 01 02 ................ | 4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................ | 4016: 01 01 01 02 00 01 02 01 02 00 01 01 01 02 00 01 ................ | 4032: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 ................ | 4048: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 ................ | 4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................ | 4080: 00 01 01 11 02 00 01 01 01 02 00 01 01 01 02 00 ................ | page 6 offset 20480 | 0: 0a 00 00 00 02 0f f5 00 0f fb 1f f5 00 00 00 00 ................ | 4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09 ................ | page 7 offset 24576 | 0: 0d 00 00 00 05 0f b8 00 0f f4 0f e9 10 d6 0f c7 ................ | 4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f ...........#auto | 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge | 4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =1.............. | end crash-53f41622dd3bf6.db }]} {} do_catchsql_test 29.1 { PRAGMA writable_schema = 1; INSERT INTO t1(a) SELECT X'819192E578DE3F'; UPDATE t1 SET b=quote(zeroblob(current_date)) WHERE t1 MATCH 't*'; INSERT INTO t1(b) VALUES(x'78'); INSERT INTO t1(t1) SELECT x FROM t2; } {1 {database disk image is malformed}} finish_test |
Changes to test/fts3corrupt5.test.
︙ | ︙ | |||
53 54 55 56 57 58 59 | if {$bCorrupt} { set res {1 {database disk image is malformed}}} do_catchsql_test 1.3.$tn.2 { SELECT * FROM ft WHERE ft MATCH $q } $res } finish_test | < | 53 54 55 56 57 58 59 | if {$bCorrupt} { set res {1 {database disk image is malformed}}} do_catchsql_test 1.3.$tn.2 { SELECT * FROM ft WHERE ft MATCH $q } $res } finish_test |
Changes to test/fts3expr5.test.
︙ | ︙ | |||
60 61 62 63 64 65 66 | test_fts3expr {(a:123)(b:234)(c:456)} } {AND {AND {PHRASE 0 0 123} {PHRASE 1 0 234}} {PHRASE 2 0 456}} do_test 2.2 { list [catch { test_fts3expr {"123" AND ( )} } msg] $msg } {1 {Error parsing expression}} finish_test | < | 60 61 62 63 64 65 66 | test_fts3expr {(a:123)(b:234)(c:456)} } {AND {AND {PHRASE 0 0 123} {PHRASE 1 0 234}} {PHRASE 2 0 456}} do_test 2.2 { list [catch { test_fts3expr {"123" AND ( )} } msg] $msg } {1 {Error parsing expression}} finish_test |
Changes to test/fts3snippet.test.
︙ | ︙ | |||
557 558 559 560 561 562 563 | do_test 4.3 { llength [db one { SELECT snippet(t4, '', '', '', 0, 150) FROM t4 WHERE t4 MATCH 'E' }] } {64} | > > | > > > > > > > > > > > > > > > > > > > > > > | 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 | do_test 4.3 { llength [db one { SELECT snippet(t4, '', '', '', 0, 150) FROM t4 WHERE t4 MATCH 'E' }] } {64} #------------------------------------------------------------------------- # Request a snippet from a query with more than 64 phrases. # do_execsql_test 5.0 { CREATE VIRTUAL TABLE t5 USING fts3(x); INSERT INTO t5 VALUES('a1 a2 a3'); INSERT INTO t5 VALUES('a4 a5 a6'); INSERT INTO t5 VALUES('a70 a71 a72'); } do_execsql_test 5.1 { SELECT snippet(t5, '[', ']') FROM t5 WHERE t5 MATCH 'a1 OR a2 OR a3 OR a4 OR a5 OR a6 OR a7 OR a8 OR a9 OR a10 OR ' || 'a11 OR a12 OR a13 OR a14 OR a15 OR a16 OR a17 OR a18 OR a19 OR a10 OR ' || 'a21 OR a22 OR a23 OR a24 OR a25 OR a26 OR a27 OR a28 OR a29 OR a20 OR ' || 'a31 OR a32 OR a33 OR a34 OR a35 OR a36 OR a37 OR a38 OR a39 OR a30 OR ' || 'a41 OR a42 OR a43 OR a44 OR a45 OR a46 OR a47 OR a48 OR a49 OR a40 OR ' || 'a51 OR a52 OR a53 OR a54 OR a55 OR a56 OR a57 OR a58 OR a59 OR a50 OR ' || 'a61 OR a62 OR a63 OR a64 OR a65 OR a66 OR a67 OR a68 OR a69 OR a60 OR ' || 'a71 OR a72 OR a73 OR a74 OR a75 OR a76 OR a77 OR a78 OR a79 OR a70' } { {[a1] [a2] [a3]} {[a4] [a5] [a6]} {[a70] [a71] [a72]} } set sqlite_fts3_enable_parentheses 0 finish_test |
Changes to test/fts4rename.test.
︙ | ︙ | |||
37 38 39 40 41 42 43 | do_catchsql_test 1.3 { ROLLBACK; DROP TABLE t1; } {0 {}} finish_test | < | 37 38 39 40 41 42 43 | do_catchsql_test 1.3 { ROLLBACK; DROP TABLE t1; } {0 {}} finish_test |
Changes to test/func.test.
︙ | ︙ | |||
1415 1416 1417 1418 1419 1420 1421 | do_execsql_test func-32.140 { SELECT test_frombind(a,b,c,e,f,$xyz+f) FROM t1; } {0} do_execsql_test func-32.150 { SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y; } {8} | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 | do_execsql_test func-32.140 { SELECT test_frombind(a,b,c,e,f,$xyz+f) FROM t1; } {0} do_execsql_test func-32.150 { SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y; } {8} # 2019-08-15 # Direct-only functions. # proc testdirectonly {x} {return [expr {$x*2}]} do_test func-33.1 { db func testdirectonly -directonly testdirectonly db eval {SELECT testdirectonly(15)} } {30} do_catchsql_test func-33.2 { CREATE VIEW v33(y) AS SELECT testdirectonly(15); SELECT * FROM v33; } {1 {testdirectonly() prohibited in triggers and views}} do_execsql_test func-33.3 { SELECT * FROM (SELECT testdirectonly(15)) AS v33; } {30} do_execsql_test func-33.4 { WITH c(x) AS (SELECT testdirectonly(15)) SELECT * FROM c; } {30} do_catchsql_test func-33.5 { WITH c(x) AS (SELECT * FROM v33) SELECT * FROM c; } {1 {testdirectonly() prohibited in triggers and views}} do_execsql_test func-33.10 { CREATE TABLE t33a(a,b); CREATE TABLE t33b(x,y); CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN INSERT INTO t33b(x,y) VALUES(testdirectonly(new.a),new.b); END; } {} do_catchsql_test func-33.11 { INSERT INTO t33a VALUES(1,2); } {1 {testdirectonly() prohibited in triggers and views}} do_execsql_test func-33.20 { ALTER TABLE t33a RENAME COLUMN a TO aaa; SELECT sql FROM sqlite_master WHERE name='r1'; } {{CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN INSERT INTO t33b(x,y) VALUES(testdirectonly(new.aaa),new.b); END}} finish_test |
Changes to test/fuzzcheck.c.
︙ | ︙ | |||
1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 | setAlarm(iTimeout); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( sqlFuzz || vdbeLimitFlag ){ sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag); } #endif do{ runSql(db, (char*)pSql->a, runFlags); }while( timeoutTest ); setAlarm(0); sqlite3_exec(db, "PRAGMA temp_store_directory=''", 0, 0, 0); sqlite3_close(db); } | > > > | 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 | setAlarm(iTimeout); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( sqlFuzz || vdbeLimitFlag ){ sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag); } #endif #ifdef SQLITE_TESTCTRL_PRNG_SEED sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, 1, db); #endif do{ runSql(db, (char*)pSql->a, runFlags); }while( timeoutTest ); setAlarm(0); sqlite3_exec(db, "PRAGMA temp_store_directory=''", 0, 0, 0); sqlite3_close(db); } |
︙ | ︙ |
Changes to test/fuzzdata7.db.
cannot compute difference between binary files
Changes to test/fuzzdata8.db.
cannot compute difference between binary files
Changes to test/in.test.
︙ | ︙ | |||
745 746 747 748 749 750 751 752 753 | } 0 do_execsql_test in-17.3 { SELECT 1 IN (CAST('1' AS text)); } 0 do_execsql_test in-17.4 { SELECT 1 IN (CAST('1' AS text) COLLATE nocase); } 0 finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 | } 0 do_execsql_test in-17.3 { SELECT 1 IN (CAST('1' AS text)); } 0 do_execsql_test in-17.4 { SELECT 1 IN (CAST('1' AS text) COLLATE nocase); } 0 # 2019-08-27 ticket https://sqlite.org/src/info/dbaf8a6820be1ece # do_execsql_test in-18.1 { DROP TABLE IF EXISTS t0; CREATE TABLE t0(c0 INT UNIQUE); INSERT INTO t0(c0) VALUES (1); SELECT * FROM t0 WHERE '1' IN (t0.c0); } {} # 2019-09-02 ticket https://www.sqlite.org/src/info/2841e99d104c6436 # For the IN_INDEX_NOOP optimization, apply REAL affinity to the LHS # values prior to comparison if the RHS has REAL affinity. # # Also ticket https://sqlite.org/src/info/29f635e0af71234b # do_execsql_test in-19.1 { DROP TABLE IF EXISTS t0; CREATE TABLE t0(c0 REAL UNIQUE); INSERT INTO t0(c0) VALUES(2.07093491255203046E18); SELECT 1 FROM t0 WHERE c0 IN ('2070934912552030444'); } {1} do_execsql_test in-19.2 { SELECT c0 IN ('2070934912552030444') FROM t0; } {1} do_execsql_test in-19.3 { SELECT c0 IN ('2070934912552030444',2,3) FROM t0; } {1} do_execsql_test in-19.4 { DROP TABLE t0; CREATE TABLE t0(c0 TEXT, c1 REAL, c2, PRIMARY KEY(c2, c0, c1)); CREATE INDEX i0 ON t0(c1 IN (c0)); INSERT INTO t0(c0, c2) VALUES (0, NULL) ON CONFLICT(c2, c1, c0) DO NOTHING; PRAGMA integrity_check; } {ok} finish_test |
Changes to test/in4.test.
︙ | ︙ | |||
222 223 224 225 226 227 228 | do_execsql_test in4-3.42 { EXPLAIN SELECT * FROM t3 WHERE x IN (10,11); } {/OpenEphemeral/} do_execsql_test in4-3.43 { SELECT * FROM t3 WHERE x IN (10); } {10 10 10} | > > > | | | | | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | do_execsql_test in4-3.42 { EXPLAIN SELECT * FROM t3 WHERE x IN (10,11); } {/OpenEphemeral/} do_execsql_test in4-3.43 { SELECT * FROM t3 WHERE x IN (10); } {10 10 10} # This test would verify that the "X IN (Y)" -> "X==Y" optimization # was working. But we have now taken that optimization out. #do_execsql_test in4-3.44 { # EXPLAIN # SELECT * FROM t3 WHERE x IN (10); #} {~/OpenEphemeral/} do_execsql_test in4-3.45 { SELECT * FROM t3 WHERE x NOT IN (10,11,99999); } {1 1 1} do_execsql_test in4-3.46 { EXPLAIN SELECT * FROM t3 WHERE x NOT IN (10,11,99999); } {/OpenEphemeral/} |
︙ | ︙ | |||
322 323 324 325 326 327 328 | INSERT INTO t6b VALUES(4,44),(5,55),(6,66); SELECT * FROM t6a, t6b WHERE a=3 AND b IN (c); } {3 4 4 44} do_execsql_test in4-6.1-eqp { EXPLAIN QUERY PLAN SELECT * FROM t6a, t6b WHERE a=3 AND b IN (c); | | | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | INSERT INTO t6b VALUES(4,44),(5,55),(6,66); SELECT * FROM t6a, t6b WHERE a=3 AND b IN (c); } {3 4 4 44} do_execsql_test in4-6.1-eqp { EXPLAIN QUERY PLAN SELECT * FROM t6a, t6b WHERE a=3 AND b IN (c); } {~/SCAN TABLE t6a/} do_execsql_test in4-6.2 { SELECT * FROM t6a, t6b WHERE a=3 AND c IN (b); } {3 4 4 44} do_execsql_test in4-6.2-eqp { EXPLAIN QUERY PLAN SELECT * FROM t6a, t6b WHERE a=3 AND c IN (b); } {~/SCAN/} finish_test |
Changes to test/in5.test.
︙ | ︙ | |||
244 245 246 247 248 249 250 251 252 | CREATE TABLE t9(a INTEGER PRIMARY KEY); INSERT INTO t9 VALUES (44), (45); } do_execsql_test 9.1 { SELECT * FROM t9 WHERE a IN (44, 45, 44, 45) } {44 45} finish_test | > > > > > > > > > > > > > > > > > | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | CREATE TABLE t9(a INTEGER PRIMARY KEY); INSERT INTO t9 VALUES (44), (45); } do_execsql_test 9.1 { SELECT * FROM t9 WHERE a IN (44, 45, 44, 45) } {44 45} #------------------------------------------------------------------------- # Test that ticket c7a117190 is fixed. # reset_db do_execsql_test 9.0 { CREATE TABLE t0(c0); CREATE VIEW v0(c0) AS SELECT LOWER(CAST('1e500' AS TEXT)) FROM t0; INSERT INTO t0(c0) VALUES (NULL); } do_execsql_test 9.1 { SELECT lower('1e500') FROM t0 WHERE rowid NOT IN (0, 0, lower('1e500')); } {1e500} do_execsql_test 9.2 { SELECT lower('1e500') FROM t0 WHERE rowid != lower('1e500'); } {1e500} finish_test |
Changes to test/index6.test.
︙ | ︙ | |||
155 156 157 158 159 160 161 | } {500} do_test index6-2.2 { execsql { EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE a=5; } } {/.* TABLE t2 USING INDEX t2a1 .*/} | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | } {500} do_test index6-2.2 { execsql { EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE a=5; } } {/.* TABLE t2 USING INDEX t2a1 .*/} ifcapable stat4 { execsql ANALYZE do_test index6-2.3stat4 { execsql { EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE a IS NOT NULL; } } {/.* TABLE t2 USING INDEX t2a1 .*/} |
︙ | ︙ | |||
433 434 435 436 437 438 439 | SELECT * FROM t0 WHERE t0.c0 IS NOT 1; } {{} row} do_execsql_test index6-14.2 { SELECT * FROM t0 WHERE CASE c0 WHEN 0 THEN 0 ELSE 1 END; } {{} row} | > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > | 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 | SELECT * FROM t0 WHERE t0.c0 IS NOT 1; } {{} row} do_execsql_test index6-14.2 { SELECT * FROM t0 WHERE CASE c0 WHEN 0 THEN 0 ELSE 1 END; } {{} row} # 2019-08-30 # Ticket https://www.sqlite.org/src/info/a6408d42b9f44462 # Ticket https://www.sqlite.org/src/info/fba33c8b1df6a915 # https://sqlite.org/src/info/bac716244fddac1fe841 # do_execsql_test index6-15.1 { DROP TABLE t0; CREATE TABLE t0(c0); INSERT INTO t0(c0) VALUES (NULL); CREATE INDEX i0 ON t0(1) WHERE c0 NOT NULL; SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) IS FALSE; } {1} do_execsql_test index6-15.2 { SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) BETWEEN FALSE AND TRUE; } {1} do_execsql_test index6-15.3 { SELECT 1 FROM t0 WHERE TRUE BETWEEN (t0.c0 IS FALSE) AND TRUE; } {1} do_execsql_test index6-15.4 { SELECT 1 FROM t0 WHERE FALSE BETWEEN FALSE AND (t0.c0 IS FALSE); } {1} do_execsql_test index6-15.5 { SELECT 1 FROM t0 WHERE (c0 IS FALSE) IN (FALSE); } {1} # 2019-09-03 # Ticket https://sqlite.org/src/info/767a8cbc6d20bd68 do_execsql_test index6-16.1 { DROP TABLE t0; CREATE TABLE t0(c0 COLLATE NOCASE, c1); CREATE INDEX i0 ON t0(0) WHERE c0 >= c1; INSERT INTO t0 VALUES('a', 'B'); SELECT c1 <= c0, c0 >= c1 FROM t0; } {1 0} do_execsql_test index6-16.2 { SELECT 2 FROM t0 WHERE c0 >= c1; } {} do_execsql_test index6-16.3 { SELECT 3 FROM t0 WHERE c1 <= c0; } {3} finish_test |
Changes to test/index7.test.
︙ | ︙ | |||
199 200 201 202 203 204 205 | } {800} do_test index7-2.2 { execsql { EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE a=5; } } {/.* TABLE t2 USING COVERING INDEX t2a1 .*/} | | | 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | } {800} do_test index7-2.2 { execsql { EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE a=5; } } {/.* TABLE t2 USING COVERING INDEX t2a1 .*/} ifcapable stat4 { do_test index7-2.3stat4 { execsql { EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE a IS NOT NULL; } } {/.* TABLE t2 USING COVERING INDEX t2a1 .*/} } else { |
︙ | ︙ |
Changes to test/indexexpr1.test.
︙ | ︙ | |||
441 442 443 444 445 446 447 448 449 | INSERT INTO t1 VALUES('1234',0),('001234',2),('01234',1); SELECT b FROM t1 WHERE lower(a)='1234' ORDER BY +b; } {0 1 2 3} do_execsql_test indexexpr-1620 { SELECT b FROM t1 WHERE lower(a)='01234' ORDER BY +b; } {} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 | INSERT INTO t1 VALUES('1234',0),('001234',2),('01234',1); SELECT b FROM t1 WHERE lower(a)='1234' ORDER BY +b; } {0 1 2 3} do_execsql_test indexexpr-1620 { SELECT b FROM t1 WHERE lower(a)='01234' ORDER BY +b; } {} # 2019-08-09 https://www.sqlite.org/src/info/9080b6227fabb466 # ExprImpliesExpr theorem prover bug: # "(NULL IS FALSE) IS FALSE" does not imply "NULL IS NULL" # do_execsql_test indexexpr-1700 { DROP TABLE IF EXISTS t0; CREATE TABLE t0(c0); INSERT INTO t0(c0) VALUES (0); CREATE INDEX i0 ON t0(NULL > c0) WHERE (NULL NOT NULL); SELECT * FROM t0 WHERE ((NULL IS FALSE) IS FALSE); } {0} # 2019-09-02 https://www.sqlite.org/src/tktview/57af00b6642ecd6848 # When the expression of an an index-on-expression references a # table column of type REAL that is actually holding an MEM_IntReal # value, be sure to use the REAL value and not the INT value when # computing the expression. # do_execsql_test indexexpr-1800 { DROP TABLE IF EXISTS t0; CREATE TABLE t0(c0 REAL, c1 TEXT); CREATE INDEX i0 ON t0(+c0, c0); INSERT INTO t0(c0) VALUES(0); SELECT CAST(+ t0.c0 AS BLOB) LIKE 0 FROM t0; } {0} do_execsql_test indexexpr-1810 { SELECT CAST(+ t0.c0 AS BLOB) LIKE '0.0' FROM t0; } {1} do_execsql_test indexexpr-1820 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(x REAL); CREATE INDEX t1x ON t1(x, +x); INSERT INTO t1(x) VALUES(2); SELECT +x FROM t1 WHERE x=2; } {2.0} finish_test |
Changes to test/indexexpr2.test.
︙ | ︙ | |||
291 292 293 294 295 296 297 | SELECT sql FROM sqlite_master WHERE tbl_name = 't0'; CREATE INDEX i0 ON t0(c0); } {{CREATE TABLE t0(c0)}} do_execsql_test 7.3 { REINDEX; } {} | > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | SELECT sql FROM sqlite_master WHERE tbl_name = 't0'; CREATE INDEX i0 ON t0(c0); } {{CREATE TABLE t0(c0)}} do_execsql_test 7.3 { REINDEX; } {} #------------------------------------------------------------------------- reset_db do_execsql_test 8.0 { CREATE TABLE t0(c0); CREATE INDEX i0 ON t0(c0) WHERE c0 NOT NULL; INSERT INTO t0(c0) VALUES (NULL); } do_execsql_test 8.1.1 { SELECT * FROM t0 WHERE ~('' BETWEEN t0.c0 AND TRUE); } {{}} do_execsql_test 8.1.2 { SELECT ~('' BETWEEN t0.c0 AND TRUE) FROM t0; } {-1} foreach {tn expr} { 1 " 0 == (34 BETWEEN c0 AND 33)" 2 " 1 != (34 BETWEEN c0 AND 33)" 3 "-1 < (34 BETWEEN c0 AND 33)" 4 "-1 <= (34 BETWEEN c0 AND 33)" 5 " 1 > (34 BETWEEN c0 AND 33)" 6 " 1 >= (34 BETWEEN c0 AND 33)" 7 " 1 - (34 BETWEEN c0 AND 33)" 8 "-1 + (34 BETWEEN c0 AND 33)" 9 " 1 | (34 BETWEEN c0 AND 33)" 10 " 1 << (34 BETWEEN c0 AND 33)" 11 " 1 >> (34 BETWEEN c0 AND 33)" 12 " 1 || (34 BETWEEN c0 AND 33)" } { do_execsql_test 8.3.$tn.1 "SELECT * FROM t0 WHERE $expr ORDER BY c0" { {} } do_execsql_test 8.3.$tn.2 "SELECT ($expr) IS TRUE FROM t0" { 1 } } do_execsql_test 8.4 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2), (3, 4); CREATE TABLE t2(x, y); } foreach {tn expr} { 1 " 0 == (a=0 AND y=1)" 2 " 1 != (a=0 AND y=1)" 3 "-1 < (a=0 AND y=1)" 4 "-1 <= (a=0 AND y=1)" 5 " 1 > (a=0 AND y=1)" 6 " 1 >= (a=0 AND y=1)" 7 " 1 - (a=0 AND y=1)" 8 "-1 + (a=0 AND y=1)" 9 " 1 | (a=0 AND y=1)" 10 "1 << (a=0 AND y=1)" 11 "1 >> (a=0 AND y=1)" 12 "1 || (a=0 AND y=1)" 13 " 0 == (10 BETWEEN y AND b)" 14 " 1 != (10 BETWEEN y AND b)" 15 "-1 < (10 BETWEEN y AND b)" 16 "-1 <= (10 BETWEEN y AND b)" 17 " 1 > (10 BETWEEN y AND b)" 18 " 1 >= (10 BETWEEN y AND b)" 19 " 1 - (10 BETWEEN y AND b)" 20 "-1 + (10 BETWEEN y AND b)" 21 " 1 | (10 BETWEEN y AND b)" 22 " 1 << (10 BETWEEN y AND b)" 23 " 1 >> (10 BETWEEN y AND b)" 24 " 1 || (10 BETWEEN y AND b)" 25 " 1 || (10 BETWEEN y AND b)" } { do_execsql_test 8.5.$tn.1 " SELECT * FROM t1 LEFT JOIN t2 WHERE $expr " {1 2 {} {} 3 4 {} {}} do_execsql_test 8.5.$tn.2 " SELECT ($expr) IS TRUE FROM t1 LEFT JOIN t2 " {1 1} } finish_test |
Changes to test/insert.test.
︙ | ︙ | |||
455 456 457 458 459 460 461 462 463 | DROP TABLE IF EXISTS t14; CREATE TABLE t14(x INTEGER PRIMARY KEY); INSERT INTO t14 VALUES(CASE WHEN 1 THEN null END); SELECT x FROM t14; } {1} integrity_check insert-99.0 finish_test | > > > > > > > > > > > > > > > > | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | DROP TABLE IF EXISTS t14; CREATE TABLE t14(x INTEGER PRIMARY KEY); INSERT INTO t14 VALUES(CASE WHEN 1 THEN null END); SELECT x FROM t14; } {1} integrity_check insert-99.0 # 2019-08-12. # do_execsql_test insert-15.1 { DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t2; CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT); CREATE INDEX i1 ON t1(b); CREATE TABLE t2(a, b); INSERT INTO t2 VALUES(4, randomblob(31000)); INSERT INTO t2 VALUES(4, randomblob(32000)); INSERT INTO t2 VALUES(4, randomblob(33000)); REPLACE INTO t1 SELECT a, b FROM t2; SELECT a, length(b) FROM t1; } {4 33000} finish_test |
Changes to test/intarray.test.
︙ | ︙ | |||
43 44 45 46 47 48 49 | set ia4 [sqlite3_intarray_create db ia4] db eval { SELECT type, name FROM temp.sqlite_master ORDER BY name } } {table ia1 table ia2 table ia3 table ia4} | | | | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | set ia4 [sqlite3_intarray_create db ia4] db eval { SELECT type, name FROM temp.sqlite_master ORDER BY name } } {table ia1 table ia2 table ia3 table ia4} # Verify the ability to DROP and recreate an intarray virtual table. do_test intarray-1.1b { db eval {DROP TABLE ia1} set rc [catch {sqlite3_intarray_create db ia1} ia1] lappend rc $ia1 } {/0 [0-9A-Z]+/} do_test intarray-1.2 { db eval { SELECT b FROM t1 WHERE a IN ia3 ORDER BY a } } {} |
︙ | ︙ |
Changes to test/intreal.test.
︙ | ︙ | |||
78 79 80 81 82 83 84 85 86 | SELECT * FROM t0, t1 WHERE ( t1.c1 >= CAST(8366271098608253588 AS REAL) AND t1.c1 <= CAST(8366271098608253588 AS REAL) ); } [list a $D] finish_test | > > > > > > > > > > > > | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | SELECT * FROM t0, t1 WHERE ( t1.c1 >= CAST(8366271098608253588 AS REAL) AND t1.c1 <= CAST(8366271098608253588 AS REAL) ); } [list a $D] # 2019-07-29 ticket ba2f4585cf495231 # db close sqlite3 db :memory: do_execsql_test 3.0 { CREATE TABLE t0 (c0 REAL, c1); CREATE UNIQUE INDEX i0 ON t0(c1, 0 | c0); INSERT INTO t0(c0) VALUES (4750228396194493326), (0); UPDATE OR REPLACE t0 SET c0 = 'a', c1 = ''; SELECT * FROM t0 ORDER BY t0.c1; PRAGMA integrity_check; } {a {} ok} finish_test |
Changes to test/join.test.
︙ | ︙ | |||
808 809 810 811 812 813 814 | 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} | | > > > > > | 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 | WHERE CASE WHEN FALSE THEN a=x ELSE 1 END; } {1 2 {} {} x 3 4 {} {} x} do_execsql_test join-15.105 { SELECT *, 'x' FROM t1 LEFT JOIN t2 WHERE a IN (1,3,x,y); } {1 2 {} {} x 3 4 {} {} x} do_execsql_test join-15.106a { SELECT *, 'x' FROM t1 LEFT JOIN t2 WHERE NOT ( 'x'='y' AND t2.y=1 ); } {1 2 {} {} x 3 4 {} {} x} do_execsql_test join-15.106b { SELECT *, 'x' FROM t1 LEFT JOIN t2 WHERE ~ ( 'x'='y' AND t2.y=1 ); } {1 2 {} {} x 3 4 {} {} x} do_execsql_test join-15.107 { SELECT *, 'x' FROM t1 LEFT JOIN t2 WHERE t2.y IS NOT 'abc' } {1 2 {} {} x 3 4 {} {} x} do_execsql_test join-15.110 { DROP TABLE t1; |
︙ | ︙ | |||
859 860 861 862 863 864 865 866 867 | CREATE TABLE t1(a INT); INSERT INTO t1(a) VALUES(1); CREATE TABLE t2(b INT); SELECT a, b FROM t1 LEFT JOIN t2 ON 0 WHERE (b IS NOT NULL)=0; } {1 {}} finish_test | > > > > > > > > > > > > > > > | 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 | CREATE TABLE t1(a INT); INSERT INTO t1(a) VALUES(1); CREATE TABLE t2(b INT); SELECT a, b FROM t1 LEFT JOIN t2 ON 0 WHERE (b IS NOT NULL)=0; } {1 {}} # 2019-08-17 ticket https://sqlite.org/src/tktview/6710d2f7a13a299728ab # Ensure that constants that derive from the right-hand table of a LEFT JOIN # are never factored out, since they are not really constant. # do_execsql_test join-17.100 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(x); INSERT INTO t1(x) VALUES(0),(1); SELECT * FROM t1 LEFT JOIN (SELECT abs(1) AS y FROM t1) ON x WHERE NOT(y='a'); } {1 1 1 1} do_execsql_test join-17.110 { SELECT * FROM t1 LEFT JOIN (SELECT abs(1)+2 AS y FROM t1) ON x WHERE NOT(y='a'); } {1 3 1 3} finish_test |
Changes to test/json104.test.
︙ | ︙ | |||
149 150 151 152 153 154 155 | do_execsql_test 405 { UPDATE obj SET x = json_set(x, '$."d"', 4); SELECT json_extract(x, '$."d"') FROM obj; } {4} finish_test | < < | 149 150 151 152 153 154 155 | do_execsql_test 405 { UPDATE obj SET x = json_set(x, '$."d"', 4); SELECT json_extract(x, '$."d"') FROM obj; } {4} finish_test |
Changes to test/like.test.
︙ | ︙ | |||
1110 1111 1112 1113 1114 1115 1116 | SELECT * FROM t1 WHERE a LIKE ' 1%'; } {{ 1x} { 1-}} do_execsql_test 16.2 { SELECT * FROM t1 WHERE a LIKE ' 1-'; } {{ 1-}} finish_test | < | 1110 1111 1112 1113 1114 1115 1116 | SELECT * FROM t1 WHERE a LIKE ' 1%'; } {{ 1x} { 1-}} do_execsql_test 16.2 { SELECT * FROM t1 WHERE a LIKE ' 1-'; } {{ 1-}} finish_test |
Changes to test/mallocA.test.
︙ | ︙ | |||
92 93 94 95 96 97 98 | faultsim_test_result [list 0 2] } do_faultsim_test 6.2 -faults oom* -body { execsql { SELECT rowid FROM t1 WHERE a='abc' AND b<'y' } } -test { faultsim_test_result [list 0 {1 2}] } | < < < < < < < < < < < < < < < < < < | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | faultsim_test_result [list 0 2] } do_faultsim_test 6.2 -faults oom* -body { execsql { SELECT rowid FROM t1 WHERE a='abc' AND b<'y' } } -test { faultsim_test_result [list 0 {1 2}] } do_execsql_test 7.0 { PRAGMA cache_size = 5; } do_faultsim_test 7 -faults oom-trans* -prep { } -body { execsql { |
︙ | ︙ |
Changes to test/minmax4.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # # Demonstration that the value returned for p is on the same row as # the maximum q. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !compound { finish_test return } do_test minmax4-1.1 { | > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # # Demonstration that the value returned for p is on the same row as # the maximum q. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix minmax4 ifcapable !compound { finish_test return } do_test minmax4-1.1 { |
︙ | ︙ | |||
144 145 146 147 148 149 150 | } {1 2 1 4 4 2 3 3 5 5} do_test minmax4-2.7 { db eval { SELECT a, min(b), b, min(c), c FROM t2 GROUP BY a ORDER BY a; } } {1 1 {} 2 2 2 3 3 5 5} | > > > > > > > > > > | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | } {1 2 1 4 4 2 3 3 5 5} do_test minmax4-2.7 { db eval { SELECT a, min(b), b, min(c), c FROM t2 GROUP BY a ORDER BY a; } } {1 1 {} 2 2 2 3 3 5 5} #------------------------------------------------------------------------- foreach {tn sql} { 1 { CREATE INDEX i1 ON t1(a) } 2 { CREATE INDEX i1 ON t1(a DESC) } 3 { } } { reset_db do_execsql_test 3.$tn.0 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(NULL, 1); } execsql $sql do_execsql_test 3.$tn.1 { SELECT min(a), b FROM t1; } {{} 1} do_execsql_test 3.$tn.2 { SELECT min(a), b FROM t1 WHERE a<50; } {{} {}} do_execsql_test 3.$tn.3 { INSERT INTO t1 VALUES(2, 2); } do_execsql_test 3.$tn.4 { SELECT min(a), b FROM t1; } {2 2} do_execsql_test 3.$tn.5 { SELECT min(a), b FROM t1 WHERE a<50; } {2 2} } #------------------------------------------------------------------------- reset_db do_execsql_test 4.0 { CREATE TABLE t0 (c0, c1); CREATE INDEX i0 ON t0(c1, c1 + 1 DESC); INSERT INTO t0(c0) VALUES (1); } do_execsql_test 4.1 { SELECT MIN(t0.c1), t0.c0 FROM t0 WHERE t0.c1 ISNULL; } {{} 1} #------------------------------------------------------------------------- reset_db do_execsql_test 5.0 { CREATE TABLE t1 (a, b); INSERT INTO t1 VALUES(123, NULL); CREATE INDEX i1 ON t1(a, b DESC); } do_execsql_test 5.1 { SELECT MIN(a) FROM t1 WHERE a=123; } {123} #------------------------------------------------------------------------- # Tests for ticket f8a7060ece. # reset_db do_execsql_test 6.1.0 { CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES(NULL, 1, 'x'); CREATE INDEX i1 ON t1(a); } do_execsql_test 6.1.1 { SELECT min(a), b, c FROM t1 WHERE c='x'; } {{} 1 x} do_execsql_test 6.1.2 { INSERT INTO t1 VALUES(1, 2, 'y'); } {} do_execsql_test 6.1.3 { SELECT min(a), b, c FROM t1 WHERE c='x'; } {{} 1 x} do_execsql_test 6.2.0 { CREATE TABLE t0(c0 UNIQUE, c1); INSERT INTO t0(c1) VALUES (0); INSERT INTO t0(c0) VALUES (0); CREATE VIEW v0(c0, c1) AS SELECT t0.c1, t0.c0 FROM t0 WHERE CAST(t0.rowid AS INT) = 1; } do_execsql_test 6.2.1 { SELECT c0, c1 FROM v0; } {0 {}} do_execsql_test 6.2.2 { SELECT v0.c0, MIN(v0.c1) FROM v0; } {0 {}} finish_test |
Added test/nulls1.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | # 2019 August 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix nulls1 do_execsql_test 1.0 { DROP TABLE IF EXISTS t3; CREATE TABLE t3(a INTEGER); INSERT INTO t3 VALUES(NULL), (10), (30), (20), (NULL); } {} for {set a 0} {$a < 3} {incr a} { foreach {tn limit} { 1 "" 2 "LIMIT 10" } { do_execsql_test 1.$a.$tn.1 " SELECT a FROM t3 ORDER BY a nULLS FIRST $limit " {{} {} 10 20 30} do_execsql_test 1.$a.$tn.2 " SELECT a FROM t3 ORDER BY a nULLS LAST $limit " {10 20 30 {} {}} do_execsql_test 1.$a.$tn.3 " SELECT a FROM t3 ORDER BY a DESC nULLS FIRST $limit " {{} {} 30 20 10} do_execsql_test 1.$a.$tn.4 " SELECT a FROM t3 ORDER BY a DESC nULLS LAST $limit " {30 20 10 {} {}} } switch $a { 0 { execsql { CREATE INDEX i1 ON t3(a) } } 1 { execsql { DROP INDEX i1 ; CREATE INDEX i1 ON t3(a DESC) } } } } #------------------------------------------------------------------------- reset_db do_execsql_test 2.0 { CREATE TABLE t2(a, b, c); CREATE INDEX i2 ON t2(a, b); INSERT INTO t2 VALUES(1, 1, 1); INSERT INTO t2 VALUES(1, NULL, 2); INSERT INTO t2 VALUES(1, NULL, 3); INSERT INTO t2 VALUES(1, 4, 4); } do_execsql_test 2.1 { SELECT * FROM t2 WHERE a=1 ORDER BY b NULLS LAST } { 1 1 1 1 4 4 1 {} 2 1 {} 3 } do_execsql_test 2.2 { SELECT * FROM t2 WHERE a=1 ORDER BY b DESC NULLS FIRST } { 1 {} 3 1 {} 2 1 4 4 1 1 1 } #------------------------------------------------------------------------- # reset_db do_execsql_test 3.0 { CREATE TABLE t1(a, b, c, d, UNIQUE (b)); } foreach {tn sql err} { 1 { CREATE INDEX i1 ON t1(a ASC NULLS LAST) } LAST 2 { CREATE INDEX i1 ON t1(a ASC NULLS FIRST) } FIRST 3 { CREATE INDEX i1 ON t1(a, b ASC NULLS LAST) } LAST 4 { CREATE INDEX i1 ON t1(a, b ASC NULLS FIRST) } FIRST 5 { CREATE INDEX i1 ON t1(a DESC NULLS LAST) } LAST 6 { CREATE INDEX i1 ON t1(a DESC NULLS FIRST) } FIRST 7 { CREATE INDEX i1 ON t1(a, b DESC NULLS LAST) } LAST 8 { CREATE INDEX i1 ON t1(a, b DESC NULLS FIRST) } FIRST 9 { CREATE TABLE t2(a, b, PRIMARY KEY(a DESC, b NULLS FIRST)) } FIRST 10 { CREATE TABLE t2(a, b, UNIQUE(a DESC NULLS FIRST, b)) } FIRST 11 { INSERT INTO t1 VALUES(1, 2, 3, 4) ON CONFLICT (b DESC NULLS LAST) DO UPDATE SET a = a+1 } LAST 12 { CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN INSERT INTO t1 VALUES(1, 2, 3, 4) ON CONFLICT (b DESC NULLS FIRST) DO UPDATE SET a = a+1; END } FIRST } { do_catchsql_test 3.1.$tn $sql "1 {unsupported use of NULLS $err}" } do_execsql_test 3.2 { CREATE TABLE first(nulls, last); INSERT INTO first(last, nulls) VALUES(100,200), (300,400), (200,300); SELECT * FROM first ORDER BY nulls; } { 200 100 300 200 400 300 } #------------------------------------------------------------------------- # ifcapable vtab { register_echo_module db do_execsql_test 4.0 { CREATE TABLE tx(a INTEGER PRIMARY KEY, b, c); CREATE INDEX i1 ON tx(b); INSERT INTO tx VALUES(1, 1, 1); INSERT INTO tx VALUES(2, NULL, 2); INSERT INTO tx VALUES(3, 3, 3); INSERT INTO tx VALUES(4, NULL, 4); INSERT INTO tx VALUES(5, 5, 5); CREATE VIRTUAL TABLE te USING echo(tx); } do_execsql_test 4.1 { SELECT * FROM tx ORDER BY b NULLS FIRST; } {2 {} 2 4 {} 4 1 1 1 3 3 3 5 5 5} do_execsql_test 4.2 { SELECT * FROM te ORDER BY b NULLS FIRST; } {2 {} 2 4 {} 4 1 1 1 3 3 3 5 5 5} do_execsql_test 4.3 { SELECT * FROM tx ORDER BY b NULLS LAST; } {1 1 1 3 3 3 5 5 5 2 {} 2 4 {} 4} do_execsql_test 4.4 { SELECT * FROM te ORDER BY b NULLS LAST; } {1 1 1 3 3 3 5 5 5 2 {} 2 4 {} 4} } #------------------------------------------------------------------------- # do_execsql_test 5.0 { CREATE TABLE t4(a, b, c); INSERT INTO t4 VALUES(1, 1, 11); INSERT INTO t4 VALUES(1, 2, 12); INSERT INTO t4 VALUES(1, NULL, 1); INSERT INTO t4 VALUES(2, NULL, 1); INSERT INTO t4 VALUES(2, 2, 12); INSERT INTO t4 VALUES(2, 1, 11); INSERT INTO t4 VALUES(3, NULL, 1); INSERT INTO t4 VALUES(3, 2, 12); INSERT INTO t4 VALUES(3, NULL, 3); } do_execsql_test 5.1 { SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST } { 1 1 11 1 2 12 1 {} 1 2 1 11 2 2 12 2 {} 1 3 2 12 3 {} 1 3 {} 3 } do_execsql_test 5.2 { CREATE INDEX t4ab ON t4(a, b); SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST } { 1 1 11 1 2 12 1 {} 1 2 1 11 2 2 12 2 {} 1 3 2 12 3 {} 1 3 {} 3 } do_eqp_test 5.3 { SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST } { QUERY PLAN `--SEARCH TABLE t4 USING INDEX t4ab (a=?) } do_execsql_test 5.4 { SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a DESC, b DESC NULLS FIRST } { 3 {} 3 3 {} 1 3 2 12 2 {} 1 2 2 12 2 1 11 1 {} 1 1 2 12 1 1 11 } do_eqp_test 5.5 { SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a DESC, b DESC NULLS FIRST } { QUERY PLAN `--SEARCH TABLE t4 USING INDEX t4ab (a=?) } #------------------------------------------------------------------------- # do_execsql_test 6.0 { CREATE TABLE t5(a, b, c); WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<200 ) INSERT INTO t5 SELECT i%2, CASE WHEN (i%10)==0 THEN NULL ELSE i END, i FROM s; } set res1 [db eval { SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c }] set res2 [db eval { SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC }] do_execsql_test 6.1.1 { CREATE INDEX t5ab ON t5(a, b, c); SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c; } $res1 do_eqp_test 6.1.2 { SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c; } { QUERY PLAN `--SEARCH TABLE t5 USING COVERING INDEX t5ab (a=?) } do_execsql_test 6.2.1 { SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC } $res2 do_eqp_test 6.2.2 { SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC } { QUERY PLAN `--SEARCH TABLE t5 USING COVERING INDEX t5ab (a=?) } #------------------------------------------------------------------------- do_execsql_test 7.0 { CREATE TABLE t71(a, b, c); CREATE INDEX t71abc ON t71(a, b, c); SELECT * FROM t71 WHERE a=1 AND b=2 ORDER BY c NULLS LAST; SELECT * FROM t71 WHERE a=1 AND b=2 ORDER BY c DESC NULLS FIRST; SELECT * FROM t71 ORDER BY a NULLS LAST; SELECT * FROM t71 ORDER BY a DESC NULLS FIRST; } finish_test |
Changes to test/pg_common.tcl.
︙ | ︙ | |||
66 67 68 69 70 71 72 | set ret } proc execsql_test {tn sql} { set res [execsql $sql] set sql [string map {string_agg group_concat} $sql] | | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | set ret } proc execsql_test {tn sql} { set res [execsql $sql] set sql [string map {string_agg group_concat} $sql] # set sql [string map [list {NULLS FIRST} {}] $sql] # set sql [string map [list {NULLS LAST} {}] $sql] puts $::fd "do_execsql_test $tn {" puts $::fd " [string trim $sql]" puts $::fd "} {$res}" puts $::fd "" } proc errorsql_test {tn sql} { |
︙ | ︙ |
Changes to test/pragma5.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 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, | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # 2017 August 25 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for the PRAGMA command. Specifically, # those pragmas that are not disabled at build time by setting: # # -DSQLITE_OMIT_INTROSPECTION_PRAGMAS # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix pragma5 if { [catch {db one "SELECT count(*) FROM pragma_function_list"}] } { |
︙ | ︙ |
Changes to test/releasetest_data.tcl.
|
| > | > > > > > > > > > > > > > > > > > > > > > > > > | > > > > | > > > > | > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | # 2019 August 01 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file implements a program that produces scripts (either shell scripts # or batch files) to implement a particular test that is part of the SQLite # release testing procedure. For example, to run veryquick.test with a # specified set of -D compiler switches. # # A "configuration" is a set of options passed to [./configure] and [make] # to build the SQLite library in a particular fashion. A "platform" is a # list of tests; most platforms are named after the hardware/OS platform # that the tests will be run on as part of the release procedure. Each # "test" is a combination of a configuration and a makefile target (e.g. # "fulltest"). The program may be invoked as follows: # set USAGE { $argv0 platforms List available platforms. $argv0 tests ?-nodebug? PLATFORM List tests in a specified platform. If the -nodebug switch is specified, synthetic debug/ndebug configurations are omitted. Each test is a combination of a configuration and a makefile target. $argv0 script ?-msvc? CONFIGURATION TARGET Given a configuration and make target, return a bash (or, if -msvc is specified, batch) script to execute the test. The first argument passed to the script must be a directory containing SQLite source code. $argv0 configurations List available configurations. } # Omit comments (text between # and \n) in a long multi-line string. # proc strip_comments {in} { regsub -all {#[^\n]*\n} $in {} out return $out } |
︙ | ︙ | |||
154 155 156 157 158 159 160 | "Apple" { -Os -DHAVE_GMTIME_R=1 -DHAVE_ISNAN=1 -DHAVE_LOCALTIME_R=1 -DHAVE_PREAD=1 -DHAVE_PWRITE=1 | < < < | 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 | "Apple" { -Os -DHAVE_GMTIME_R=1 -DHAVE_ISNAN=1 -DHAVE_LOCALTIME_R=1 -DHAVE_PREAD=1 -DHAVE_PWRITE=1 -DHAVE_UTIME=1 -DSQLITE_DEFAULT_CACHE_SIZE=1000 -DSQLITE_DEFAULT_CKPTFULLFSYNC=1 -DSQLITE_DEFAULT_MEMSTATUS=1 -DSQLITE_DEFAULT_PAGE_SIZE=1024 -DSQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS=1 -DSQLITE_ENABLE_API_ARMOR=1 -DSQLITE_ENABLE_AUTO_PROFILE=1 -DSQLITE_ENABLE_FLOCKTIMEOUT=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS3_TOKENIZER=1 -DSQLITE_ENABLE_PERSIST_WAL=1 -DSQLITE_ENABLE_PURGEABLE_PCACHE=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_SNAPSHOT=1 # -DSQLITE_ENABLE_SQLLOG=1 -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 -DSQLITE_MAX_LENGTH=2147483645 |
︙ | ︙ | |||
208 209 210 211 212 213 214 | -DSQLITE_DISABLE_FTS4_DEFERRED -DSQLITE_ENABLE_RTREE --enable-json1 --enable-fts5 } "No-lookaside" { -DSQLITE_TEST_REALLOC_STRESS=1 -DSQLITE_OMIT_LOOKASIDE=1 | < > > > > > > > > > | | | | > > > | | | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | -DSQLITE_DISABLE_FTS4_DEFERRED -DSQLITE_ENABLE_RTREE --enable-json1 --enable-fts5 } "No-lookaside" { -DSQLITE_TEST_REALLOC_STRESS=1 -DSQLITE_OMIT_LOOKASIDE=1 } "Valgrind" { -DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_HIDDEN_COLUMNS --enable-json1 } "Windows-Memdebug" { MEMDEBUG=1 DEBUG=3 } "Windows-Win32Heap" { WIN32HEAP=1 DEBUG=4 } # The next group of configurations are used only by the # Failure-Detection platform. They are all the same, but we need # different names for them all so that they results appear in separate # subdirectories. # Fail0 {-O0} Fail2 {-O0} Fail3 {-O0} Fail4 {-O0} FuzzFail1 {-O0} FuzzFail2 {-O0} }] if {$tcl_platform(os)=="Darwin"} { lappend Configs(Apple -DSQLITE_ENABLE_LOCKING_STYLE=1 } array set ::Platforms [strip_comments { Linux-x86_64 { "Check-Symbols*" checksymbols "Fast-One" "fuzztest test" "Debug-One" "mptest test" "Have-Not" test "Secure-Delete" test "Unlock-Notify" "QUICKTEST_INCLUDE=notify2.test test" "User-Auth" tcltest "Update-Delete-Limit" test "Extra-Robustness" test "Device-Two" "threadtest test" "No-lookaside" test "Devkit" test "Apple" test "Sanitize" {QUICKTEST_OMIT=func4.test,nan.test test} "Device-One" fulltest "Default" "threadtest fulltest" "Valgrind*" valgrindtest } Linux-i686 { "Devkit" test "Have-Not" test "Unlock-Notify" "QUICKTEST_INCLUDE=notify2.test test" "Device-One" test "Device-Two" test |
︙ | ︙ | |||
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | "Locking-Style" "mptest test" "Have-Not" test "Apple" "threadtest fulltest" } "Windows NT-intel" { "Stdcall" test "Have-Not" test "Default" "mptest fulltestonly" } "Windows NT-amd64" { "Stdcall" test "Have-Not" test "Default" "mptest fulltestonly" } # The Failure-Detection platform runs various tests that deliberately # fail. This is used as a test of this script to verify that this script # correctly identifies failures. # Failure-Detection { | > > > > | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | "Locking-Style" "mptest test" "Have-Not" test "Apple" "threadtest fulltest" } "Windows NT-intel" { "Stdcall" test "Have-Not" test "Windows-Memdebug*" test "Windows-Win32Heap*" test "Default" "mptest fulltestonly" } "Windows NT-amd64" { "Stdcall" test "Have-Not" test "Windows-Memdebug*" test "Windows-Win32Heap*" test "Default" "mptest fulltestonly" } # The Failure-Detection platform runs various tests that deliberately # fail. This is used as a test of this script to verify that this script # correctly identifies failures. # Failure-Detection { Fail0* "TEST_FAILURE=0 test" Sanitize* "TEST_FAILURE=1 test" Fail2* "TEST_FAILURE=2 valgrindtest" Fail3* "TEST_FAILURE=3 valgrindtest" Fail4* "TEST_FAILURE=4 test" FuzzFail1* "TEST_FAILURE=5 test" FuzzFail2* "TEST_FAILURE=5 valgrindtest" } }] # Configuration verification: Check that each entry in the list of configs # specified for each platforms exists. # foreach {key value} [array get ::Platforms] { foreach {v t} $value { if {[string range $v end end]=="*"} { set v [string range $v 0 end-1] } if {0==[info exists ::Configs($v)]} { puts stderr "No such configuration: \"$v\"" exit -1 } } } proc usage {} { global argv0 puts stderr [subst $::USAGE] exit 1 } proc is_prefix {p str min} { set n [string length $p] if {$n<$min} { return 0 } if {[string range $str 0 [expr $n-1]]!=$p} { return 0 } return 1 } proc main_configurations {} { foreach k [lsort [array names ::Configs]] { puts $k } } proc main_platforms {} { foreach k [lsort [array names ::Platforms]] { puts "\"$k\"" } } proc main_script {args} { set bMsvc 0 set nArg [llength $args] if {$nArg==3} { if {![is_prefix [lindex $args 0] -msvc 2]} usage set bMsvc 1 } elseif {$nArg<2 || $nArg>3} { usage } set config [lindex $args end-1] set target [lindex $args end] set opts [list] ;# OPTS value set cflags [expr {$bMsvc ? "-Zi" : "-g"}] ;# CFLAGS value set makeOpts [list] ;# Extra args for [make] set configOpts [list] ;# Extra args for [configure] if {$::tcl_platform(platform)=="windows" || $bMsvc} { lappend opts -DSQLITE_OS_WIN=1 } else { lappend opts -DSQLITE_OS_UNIX=1 } # Figure out if this is a synthetic ndebug or debug configuration. # set bRemoveDebug 0 if {[string match *-ndebug $config]} { set bRemoveDebug 1 set config [string range $config 0 end-7] } if {[string match *-debug $config]} { lappend opts -DSQLITE_DEBUG lappend opts -DSQLITE_EXTRA_IFNULLROW set config [string range $config 0 end-6] } # Ensure that the named configuration exists. # if {![info exists ::Configs($config)]} { puts stderr "No such config: $config" exit 1 } # Loop through the parameters of the nominated configuration, updating # $opts, $cflags, $makeOpts and $configOpts along the way. Rules are as # follows: # # 1. If the parameter begins with a "*", discard it. # # 2. If $bRemoveDebug is set and the parameter is -DSQLITE_DEBUG or # -DSQLITE_DEBUG=1, discard it # # 3. If the parameter begins with "-D", add it to $opts. # # 4. If the parameter begins with "--" add it to $configOpts. Unless # this command is preparing a script for MSVC - then add an # equivalent to $makeOpts or $opts. # # 5. If the parameter begins with "-" add it to $cflags. If in MSVC # mode and the parameter is an -O<integer> option, instead add # an OPTIMIZATIONS=<integer> switch to $makeOpts. # # 6. If none of the above apply, add the parameter to $makeOpts # foreach param $::Configs($config) { if {[string range $param 0 0]=="*"} continue if {$bRemoveDebug} { if {$param=="-DSQLITE_DEBUG" || $param=="-DSQLITE_DEBUG=1" || $param=="-DSQLITE_MEMDEBUG" || $param=="-DSQLITE_MEMDEBUG=1" } { continue } } if {[string range $param 0 1]=="-D"} { lappend opts $param continue } if {[string range $param 0 1]=="--"} { if {$bMsvc} { switch -- $param { --disable-amalgamation { lappend makeOpts USE_AMALGAMATION=0 } --disable-shared { lappend makeOpts USE_CRT_DLL=0 DYNAMIC_SHELL=0 } --enable-fts5 { lappend opts -DSQLITE_ENABLE_FTS5 } --enable-json1 { lappend opts -DSQLITE_ENABLE_JSON1 } --enable-shared { lappend makeOpts USE_CRT_DLL=1 DYNAMIC_SHELL=1 } --enable-session { lappend opts -DSQLITE_ENABLE_PREUPDATE_HOOK lappend opts -DSQLITE_ENABLE_SESSION } default { error "Cannot translate $param for MSVC" } } } else { lappend configOpts $param } continue } if {[string range $param 0 0]=="-"} { if {$bMsvc && [regexp -- {^-O(\d+)$} $param -> level]} { lappend makeOpts OPTIMIZATIONS=$level } else { lappend cflags $param } continue } lappend makeOpts $param } # Some configurations specify -DHAVE_USLEEP=0. For all others, add # -DHAVE_USLEEP=1. # if {[lsearch $opts "-DHAVE_USLEEP=0"]<0} { lappend opts -DHAVE_USLEEP=1 } if {$bMsvc==0} { puts {set -e} puts {} puts {if [ "$#" -ne 1 ] ; then} puts { echo "Usage: $0 <sqlite-src-dir>" } puts { exit -1 } puts {fi } puts {SRCDIR=$1} puts {} puts "TCL=\"[::tcl::pkgconfig get libdir,install]\"" puts "\$SRCDIR/configure --with-tcl=\$TCL $configOpts" puts {} puts {OPTS=" -DSQLITE_NO_SYNC=1"} foreach o $opts { puts "OPTS=\"\$OPTS $o\"" } puts {} puts "CFLAGS=\"$cflags\"" puts {} puts "make $target \"CFLAGS=\$CFLAGS\" \"OPTS=\$OPTS\" $makeOpts" } else { puts {set SRCDIR=%1} set makecmd "nmake /f %SRCDIR%\\Makefile.msc TOP=%SRCDIR% $target " append makecmd "\"CFLAGS=$cflags\" \"OPTS=$opts\" $makeOpts" puts "set TMP=%CD%" puts $makecmd } } proc main_tests {args} { set bNodebug 0 set nArg [llength $args] if {$nArg==2} { if {[is_prefix [lindex $args 0] -nodebug 2]} { set bNodebug 1 } elseif {[is_prefix [lindex $args 0] -debug 2]} { set bNodebug 0 } else usage } elseif {$nArg==0 || $nArg>2} { usage } set p [lindex $args end] if {![info exists ::Platforms($p)]} { puts stderr "No such platform: $p" exit 1 } foreach {config target} $::Platforms($p) { set bNosynthetic 0 if {[string range $config end end]=="*"} { set bNosynthetic 1 set config [string range $config 0 end-1] } puts "$config \"$target\"" if {$bNodebug==0 && $bNosynthetic==0} { set iHas [string first SQLITE_DEBUG $::Configs($config)] if {$iHas>=0} { puts "$config-ndebug \"test\"" } else { puts "$config-debug \"test\"" } } } } if {[llength $argv]==0} { usage } set cmd [lindex $argv 0] set n [expr [llength $argv]-1] if {[string match ${cmd}* configurations] && $n==0} { main_configurations } elseif {[string match ${cmd}* script]} { main_script {*}[lrange $argv 1 end] } elseif {[string match ${cmd}* platforms] && $n==0} { main_platforms } elseif {[string match ${cmd}* tests]} { main_tests {*}[lrange $argv 1 end] } else { usage } |
Changes to test/rowvalue.test.
︙ | ︙ | |||
552 553 554 555 556 557 558 559 560 | # do_execsql_test 21.0 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(a,b,PRIMARY KEY(b,b)); INSERT INTO t1 VALUES(1,2),(3,4),(5,6); SELECT * FROM t1 WHERE (a,b) IN (VALUES(1,2)); } {1 2} finish_test | > > > > > > > > > > > > > | 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 | # do_execsql_test 21.0 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(a,b,PRIMARY KEY(b,b)); INSERT INTO t1 VALUES(1,2),(3,4),(5,6); SELECT * FROM t1 WHERE (a,b) IN (VALUES(1,2)); } {1 2} # 2019-08-09: Multi-column subquery on the RHS of an IN operator. # do_execsql_test 22.100 { SELECT (SELECT 3,4 UNION SELECT 5,6 ORDER BY 1) IN (SELECT 3,4); SELECT (SELECT 3,4 UNION SELECT 5,6 ORDER BY 1) IN (SELECT 5,6); SELECT (SELECT 5,6 UNION SELECT 3,4 ORDER BY 1) IN (SELECT 3,4); SELECT (SELECT 5,6 UNION SELECT 3,4 ORDER BY 1) IN (SELECT 5,6); SELECT (SELECT 3,4 UNION SELECT 5,6 ORDER BY 1 DESC) IN (SELECT 3,4); SELECT (SELECT 3,4 UNION SELECT 5,6 ORDER BY 1 DESC) IN (SELECT 5,6); SELECT (SELECT 5,6 UNION SELECT 3,4 ORDER BY 1 DESC) IN (SELECT 3,4); SELECT (SELECT 5,6 UNION SELECT 3,4 ORDER BY 1 DESC) IN (SELECT 5,6); } {1 0 1 0 0 1 0 1} finish_test |
Changes to test/rowvalue7.test.
︙ | ︙ | |||
51 52 53 54 55 56 57 58 | UPDATE t1 SET (c,d) = (SELECT x,y,z FROM t2 WHERE w=a); } {1 {2 columns assigned 3 values}} do_catchsql_test 2.2 { UPDATE t1 SET (b,c,d) = (SELECT x,y FROM t2 WHERE w=a); } {1 {3 columns assigned 2 values}} finish_test | > > > > > > > > > > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | UPDATE t1 SET (c,d) = (SELECT x,y,z FROM t2 WHERE w=a); } {1 {2 columns assigned 3 values}} do_catchsql_test 2.2 { UPDATE t1 SET (b,c,d) = (SELECT x,y FROM t2 WHERE w=a); } {1 {3 columns assigned 2 values}} # 2019-08-26 # ticket https://www.sqlite.org/src/info/78acc9d40f0786e8 # do_catchsql_test 3.0 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,2); UPDATE t1 SET (a,a,a,b)=(SELECT 99,100); } {1 {4 columns assigned 2 values}} finish_test |
Changes to test/schema.test.
︙ | ︙ | |||
205 206 207 208 209 210 211 | do_test schema-7.4 { sqlite3_finalize $::STMT } {SQLITE_SCHEMA} } #--------------------------------------------------------------------- # Tests 8.1 and 8.2 check that prepared statements are invalidated when | | > > > | | > > > > > > > > > | 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 | do_test schema-7.4 { sqlite3_finalize $::STMT } {SQLITE_SCHEMA} } #--------------------------------------------------------------------- # Tests 8.1 and 8.2 check that prepared statements are invalidated when # the authorization function is set to a non-null function. Tests 8.11 # and 8.12 verify that no invalidations occur when the authorizer is # cleared. # ifcapable auth { proc noop_auth {args} {return SQLITE_OK} do_test schema-8.1 { set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL] db auth noop_auth sqlite3_step $::STMT } {SQLITE_ERROR} do_test schema-8.2 { sqlite3_finalize $::STMT } {SQLITE_SCHEMA} do_test schema-8.11 { set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL] db auth {} sqlite3_step $::STMT } {SQLITE_ROW} do_test schema-8.12 { sqlite3_finalize $::STMT } {SQLITE_OK} } #--------------------------------------------------------------------- # schema-9.1: Test that if a table is dropped by one database connection, # other database connections are aware of the schema change. # schema-9.2: Test that if a view is dropped by one database connection, # other database connections are aware of the schema change. |
︙ | ︙ |
Changes to test/select1.test.
︙ | ︙ | |||
1095 1096 1097 1098 1099 1100 1101 1102 1103 | do_execsql_test select1-17.2 { SELECT * FROM t1,(SELECT * FROM t2 WHERE y=2 ORDER BY y,z LIMIT 4); } {1 2 3} do_execsql_test select1-17.3 { SELECT * FROM t1,(SELECT * FROM t2 WHERE y=2 UNION ALL SELECT * FROM t2 WHERE y=3 ORDER BY y,z LIMIT 4); } {1 2 3} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 | do_execsql_test select1-17.2 { SELECT * FROM t1,(SELECT * FROM t2 WHERE y=2 ORDER BY y,z LIMIT 4); } {1 2 3} do_execsql_test select1-17.3 { SELECT * FROM t1,(SELECT * FROM t2 WHERE y=2 UNION ALL SELECT * FROM t2 WHERE y=3 ORDER BY y,z LIMIT 4); } {1 2 3} # 2019-07-24 Ticket https://sqlite.org/src/tktview/c52b09c7f38903b1311 # do_execsql_test select1-18.1 { DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t2; CREATE TABLE t1(c); CREATE TABLE t2(x PRIMARY KEY, y); INSERT INTO t1(c) VALUES(123); INSERT INTO t2(x) VALUES(123); SELECT x FROM t2, t1 WHERE x BETWEEN c AND null OR x AND x IN ((SELECT x FROM (SELECT x FROM t2, t1 WHERE x BETWEEN (SELECT x FROM (SELECT x COLLATE rtrim FROM t2, t1 WHERE x BETWEEN c AND null OR x AND x IN (c)), t1 WHERE x BETWEEN c AND null OR x AND x IN (c)) AND null OR NOT EXISTS(SELECT -4.81 FROM t1, t2 WHERE x BETWEEN c AND null OR x AND x IN ((SELECT x FROM (SELECT x FROM t2, t1 WHERE x BETWEEN (SELECT x FROM (SELECT x BETWEEN c AND null OR x AND x IN (c)), t1 WHERE x BETWEEN c AND null OR x AND x IN (c)) AND null OR x AND x IN (c)), t1 WHERE x BETWEEN c AND null OR x AND x IN (c)))) AND x IN (c) ), t1 WHERE x BETWEEN c AND null OR x AND x IN (c))); } {} do_execsql_test select1-18.2 { DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t2; CREATE TABLE t1(c); CREATE TABLE t2(x PRIMARY KEY, y); INSERT INTO t1(c) VALUES(123); INSERT INTO t2(x) VALUES(123); SELECT x FROM t2, t1 WHERE x BETWEEN c AND (c+1) OR x AND x IN ((SELECT x FROM (SELECT x FROM t2, t1 WHERE x BETWEEN (SELECT x FROM (SELECT x COLLATE rtrim FROM t2, t1 WHERE x BETWEEN c AND (c+1) OR x AND x IN (c)), t1 WHERE x BETWEEN c AND (c+1) OR x AND x IN (c)) AND (c+1) OR NOT EXISTS(SELECT -4.81 FROM t1, t2 WHERE x BETWEEN c AND (c+1) OR x AND x IN ((SELECT x FROM (SELECT x FROM t2, t1 WHERE x BETWEEN (SELECT x FROM (SELECT x BETWEEN c AND (c+1) OR x AND x IN (c)), t1 WHERE x BETWEEN c AND (c+1) OR x AND x IN (c)) AND (c+1) OR x AND x IN (c)), t1 WHERE x BETWEEN c AND (c+1) OR x AND x IN (c)))) AND x IN (c) ), t1 WHERE x BETWEEN c AND (c+1) OR x AND x IN (c))); } {123} do_execsql_test select1-18.3 { SELECT 1 FROM t1 WHERE ( SELECT 2 FROM t2 WHERE ( SELECT 3 FROM ( SELECT x FROM t2 WHERE x=c OR x=(SELECT x FROM (VALUES(0))) ) WHERE x>c OR x=c ) ); } {1} do_execsql_test select1-18.4 { SELECT 1 FROM t1, t2 WHERE ( SELECT 3 FROM ( SELECT x FROM t2 WHERE x=c OR x=(SELECT x FROM (VALUES(0))) ) WHERE x>c OR x=c ); } {1} finish_test |
Changes to test/skipscan1.test.
︙ | ︙ | |||
230 231 232 233 234 235 236 | EXPLAIN QUERY PLAN SELECT xh, loc FROM t5 WHERE loc >= 'M' AND loc < 'N'; } {/.*COVERING INDEX t5i1 .*/} do_execsql_test skipscan1-5.2 { ANALYZE; DELETE FROM sqlite_stat1; DROP TABLE IF EXISTS sqlite_stat4; | < | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | EXPLAIN QUERY PLAN SELECT xh, loc FROM t5 WHERE loc >= 'M' AND loc < 'N'; } {/.*COVERING INDEX t5i1 .*/} do_execsql_test skipscan1-5.2 { ANALYZE; DELETE FROM sqlite_stat1; DROP TABLE IF EXISTS sqlite_stat4; INSERT INTO sqlite_stat1 VALUES('t5','t5i1','2702931 3 2 2 2 2'); INSERT INTO sqlite_stat1 VALUES('t5','t5i2','2702931 686 2 2 2'); ANALYZE sqlite_master; } {} db cache flush do_execsql_test skipscan1-5.3 { EXPLAIN QUERY PLAN |
︙ | ︙ | |||
368 369 370 371 372 373 374 375 376 | do_execsql_test skipscan1-2.3eqp { EXPLAIN QUERY PLAN SELECT a,b,c,d,'|' FROM t6 WHERE d<>99 AND b=345 ORDER BY a DESC; } {/* USING INDEX t6abc (ANY(a) AND b=?)*/} do_execsql_test skipscan1-2.3 { SELECT a,b,c,d,'|' FROM t6 WHERE d<>99 AND b=345 ORDER BY a DESC; } {} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | do_execsql_test skipscan1-2.3eqp { EXPLAIN QUERY PLAN SELECT a,b,c,d,'|' FROM t6 WHERE d<>99 AND b=345 ORDER BY a DESC; } {/* USING INDEX t6abc (ANY(a) AND b=?)*/} do_execsql_test skipscan1-2.3 { SELECT a,b,c,d,'|' FROM t6 WHERE d<>99 AND b=345 ORDER BY a DESC; } {} # 2019-07-29 Ticket ced41c7c7d6b4d36 # A skipscan query is not order-distinct # db close sqlite3 db :memory: do_execsql_test skipscan1-3.1 { CREATE TABLE t1 (c1, c2, c3, c4, PRIMARY KEY(c4, c3)); INSERT INTO t1 VALUES(3,0,1,NULL); INSERT INTO t1 VALUES(0,4,1,NULL); INSERT INTO t1 VALUES(5,6,1,NULL); INSERT INTO t1 VALUES(0,4,1,NULL); ANALYZE sqlite_master; INSERT INTO sqlite_stat1 VALUES('t1','sqlite_autoindex_t1_1','18 18 6'); ANALYZE sqlite_master; SELECT DISTINCT quote(c1), quote(c2), quote(c3), quote(c4), '|' FROM t1 WHERE t1.c3 = 1; } {3 0 1 NULL | 0 4 1 NULL | 5 6 1 NULL |} do_eqp_test skipscan1-3.2 { SELECT DISTINCT quote(c1), quote(c2), quote(c3), quote(c4), '|' FROM t1 WHERE t1.c3 = 1; } { QUERY PLAN |--SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (ANY(c4) AND c3=?) `--USE TEMP B-TREE FOR DISTINCT } finish_test |
Changes to test/tclsqlite.test.
︙ | ︙ | |||
38 39 40 41 42 43 44 | set v [catch {sqlite3} msg] regsub {really_sqlite3} $msg {sqlite3} msg lappend v $msg } [list 1 "wrong # args: should be \"$r\""] do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | set v [catch {sqlite3} msg] regsub {really_sqlite3} $msg {sqlite3} msg lappend v $msg } [list 1 "wrong # args: should be \"$r\""] do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg } {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, config, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}} do_test tcl-1.2.1 { set v [catch {db cache bogus} msg] lappend v $msg } {1 {bad option "bogus": must be flush or size}} do_test tcl-1.2.2 { set v [catch {db cache} msg] lappend v $msg |
︙ | ︙ | |||
785 786 787 788 789 790 791 | do_test 17.6.2 { list [catch { db function xyz -return ret } msg] $msg } {1 {option requires an argument: -return}} do_test 17.6.3 { list [catch { db function xyz -n object ret } msg] $msg | | | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | do_test 17.6.2 { list [catch { db function xyz -return ret } msg] $msg } {1 {option requires an argument: -return}} do_test 17.6.3 { list [catch { db function xyz -n object ret } msg] $msg } {1 {bad option "-n": must be -argcount, -deterministic, -directonly, or -returntype}} # 2019-02-28: The "bind_fallback" command. # do_test 18.100 { unset -nocomplain bindings abc def ghi jkl mno e01 e02 set bindings(abc) [expr {1+2}] set bindings(def) {hello} |
︙ | ︙ |
Changes to test/tempdb2.test.
︙ | ︙ | |||
93 94 95 96 97 98 99 | } do_execsql_test 2.2 { SELECT b FROM t1 WHERE a = 10001; } "[int2str 1001][int2str 1001][int2str 1001]" finish_test | < | 93 94 95 96 97 98 99 | } do_execsql_test 2.2 { SELECT b FROM t1 WHERE a = 10001; } "[int2str 1001][int2str 1001][int2str 1001]" finish_test |
Added test/tkt-18458b1a.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | # 2019 September 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. In particular, # that problems related to ticket [18458b1a] have been fixed. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix tkt-18458b1a foreach tn {1 2} { reset_db if {$tn==1} { # Disable the flattener and push-down optimizations optimization_control db query-flattener 0 optimization_control db push-down 0 } else { # Enable them optimization_control db query-flattener 1 optimization_control db push-down 1 } db cache size 0 do_execsql_test $tn.1.1 { CREATE TABLE t0(c0 COLLATE NOCASE); INSERT INTO t0(c0) VALUES ('B'); CREATE VIEW v0(c0, c1) AS SELECT DISTINCT t0.c0, 'a' FROM t0; } do_execsql_test $tn.1.2 { SELECT count(*) FROM v0 WHERE c1 >= c0; } 1 do_execsql_test $tn.1.3 { SELECT count(*) FROM v0 WHERE NOT NOT (c1 >= c0); } 1 do_execsql_test $tn.1.4 { SELECT count(*) FROM v0 WHERE ((c1 >= c0) OR 0+0); } 1 } finish_test |
Added test/tkt-a7debbe0.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | # 2019 September 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. In particular, # that problems related to ticket a7debbe0ad1 have been fixed. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix tkt-a7debbe0 foreach tn {1 2} { reset_db if {$tn==1} { # Disable the flattener optimization_control db query-flattener 0 } else { # Enable the flattener optimization_control db query-flattener 1 } do_execsql_test $tn.1.0 { CREATE TABLE t0(xyz INTEGER); INSERT INTO t0(xyz) VALUES(456); CREATE VIEW v2(a, B) AS SELECT 'a', 'B' COLLATE NOCASE FROM t0; CREATE TABLE t2(a, B COLLATE NOCASE); INSERT INTO t2 VALUES('a', 'B'); CREATE VIEW v3(a, B) AS SELECT 'a' COLLATE BINARY, 'B' COLLATE NOCASE FROM t0; CREATE VIEW v4(a, B) AS SELECT 'a', +CAST('B' COLLATE NOCASE AS TEXT) FROM t0; CREATE VIEW v5(a, B) AS SELECT 'a', ('B' COLLATE NOCASE) || '' FROM t0; } # Table t2 and views v2 through v5 should all be equivalent. do_execsql_test $tn.1.1.1 { SELECT a >= B FROM t2; } 1 do_execsql_test $tn.1.1.2 { SELECT 'a' >= 'B' COLLATE NOCASE } 0 do_execsql_test $tn.1.1.3 { SELECT a >= B FROM v2 } 1 do_execsql_test $tn.1.1.4 { SELECT a >= B FROM v3 } 1 do_execsql_test $tn.1.1.5 { SELECT a >= B FROM v4 } 1 do_execsql_test $tn.1.1.6 { SELECT a >= B FROM v5 } 1 do_execsql_test $tn.1.2.1 { SELECT B < a FROM t2 } 0 do_execsql_test $tn.1.2.2 { SELECT 'B' COLLATE NOCASE < 'a' } 0 do_execsql_test $tn.1.2.3 { SELECT B < a FROM v2 } 0 do_execsql_test $tn.1.2.4 { SELECT B < a FROM v3 } 0 do_execsql_test $tn.1.2.5 { SELECT a < B FROM v4 } 0 do_execsql_test $tn.1.2.6 { SELECT a < B FROM v5 } 0 #------------------------------------------------------------------------- do_execsql_test $tn.2.0 { CREATE TABLE t5(a, b COLLATE NOCASE); INSERT INTO t5 VALUES(1, 'XYZ'); } # Result should be 0, as column "xyz" from the sub-query has implicit # collation sequence BINARY. do_execsql_test $tn.2.1 { SELECT xyz==b FROM ( SELECT a, 'xyz' AS xyz FROM t5 ), t5; } {0} # Result should be 1, as literal 'xyz' has no collation sequence, so # the comparison uses the implicit collation sequence of the RHS - NOCASE. do_execsql_test $tn.2.2 { SELECT 'xyz'==b FROM ( SELECT a, 'xyz' AS xyz FROM t5 ), t5; } {1} #----------------------------------------------------------------------- # The test case submitted with the ticket. # do_execsql_test $tn.3.0 { DROP TABLE t0; DROP VIEW v2; CREATE TABLE t0(c0); INSERT INTO t0(c0) VALUES(''); CREATE VIEW v2(c0, c1) AS SELECT 'B' COLLATE NOCASE, 'a' FROM t0 ORDER BY t0.c0; SELECT SUM(count) FROM ( SELECT v2.c1 BETWEEN v2.c0 AND v2.c1 as count FROM v2 ); } 1 # The result is 1, as the collation used is the implicit collation sequence # of v2.c1 - BINARY. do_execsql_test $tn.3.1 { SELECT v2.c1 BETWEEN v2.c0 AND v2.c1 as count FROM v2; } 1 } finish_test |
Changes to test/tkt-cbd054fa6b.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | # This file implements tests to verify that ticket [cbd054fa6b] has been # fixed. # set testdir [file dirname $argv0] source $testdir/tester.tcl | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # This file implements tests to verify that ticket [cbd054fa6b] has been # fixed. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !stat4 { finish_test return } proc s {blob} { set ret "" binary scan $blob c* bytes |
︙ | ︙ | |||
51 52 53 54 55 56 57 | INSERT INTO t1 VALUES (NULL, 'H'); INSERT INTO t1 VALUES (NULL, 'I'); SELECT count(*) FROM t1; } } {10} do_test tkt-cbd05-1.2 { db eval { ANALYZE; } | < | | | | | | < < < < < < | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | INSERT INTO t1 VALUES (NULL, 'H'); INSERT INTO t1 VALUES (NULL, 'I'); SELECT count(*) FROM t1; } } {10} do_test tkt-cbd05-1.2 { db eval { ANALYZE; } db eval { PRAGMA writable_schema = 1; CREATE VIEW vvv AS SELECT tbl,idx,neq,nlt,ndlt,test_extract(sample,0) AS sample FROM sqlite_stat4; PRAGMA writable_schema = 0; } } {} do_test tkt-cbd05-1.3 { execsql { SELECT tbl,idx,group_concat(s(sample),' ') FROM vvv WHERE idx = 't1_x' |
︙ | ︙ |
Changes to test/trigger1.test.
︙ | ︙ | |||
763 764 765 766 767 768 769 770 771 | } {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 | > > > > > > > > > > > > > > | 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 | } {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} # 2019-08-26 Chromium sqlite3_fts3_lpm_fuzzer find. # db close sqlite3 db :memory: do_execsql_test trigger1-20.1 { CREATE TABLE t20_1(x); ATTACH ':memory:' AS aux; CREATE TABLE aux.t20_2(y); CREATE TABLE aux.t20_3(z); CREATE TEMP TRIGGER r20_3 AFTER INSERT ON t20_2 BEGIN UPDATE t20_3 SET z=z+1; END; DETACH aux; DROP TRIGGER r20_3; } {} finish_test |
Changes to test/triggerC.test.
︙ | ︙ | |||
1068 1069 1070 1071 1072 1073 1074 | } do_catchsql_test 17.1 { INSERT INTO xyz VALUES('hello', 2, 3); } {1 {datatype mismatch}} finish_test | < | 1068 1069 1070 1071 1072 1073 1074 | } do_catchsql_test 17.1 { INSERT INTO xyz VALUES('hello', 2, 3); } {1 {datatype mismatch}} finish_test |
Changes to test/upsert1.test.
︙ | ︙ | |||
206 207 208 209 210 211 212 213 214 | DELETE FROM t1; INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5) ON CONFLICT(b) DO UPDATE SET c=excluded.c; SELECT * FROM t1; } {1 2 33 4 5} finish_test | > > > > > > > > > > | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | DELETE FROM t1; INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5); INSERT INTO t1(a,b,c,d,e) VALUES(1,2,33,44,5) ON CONFLICT(b) DO UPDATE SET c=excluded.c; SELECT * FROM t1; } {1 2 33 4 5} # 2019-08-30 ticket https://sqlite.org/src/info/5a3dba8104421320 do_execsql_test upsert1-800 { DROP TABLE IF EXISTS t0; CREATE TABLE t0(c0 REAL UNIQUE, c1); CREATE UNIQUE INDEX test800i0 ON t0(0 || c1); INSERT INTO t0(c0, c1) VALUES (1, 2), (2, 1); INSERT INTO t0(c0) VALUES (1) ON CONFLICT(c0) DO UPDATE SET c1=excluded.c0; PRAGMA integrity_check; REINDEX; } {ok} finish_test |
Changes to test/view.test.
︙ | ︙ | |||
34 35 36 37 38 39 40 41 42 43 44 45 46 47 | do_test view-1.1 { execsql { BEGIN; CREATE VIEW IF NOT EXISTS v1 AS SELECT a,b FROM t1; SELECT * FROM v1 ORDER BY a; } } {1 2 4 5 7 8} do_test view-1.2 { catchsql { ROLLBACK; SELECT * FROM v1 ORDER BY a; } } {1 {no such table: v1}} do_test view-1.3 { | > > > > > > > > > > > > | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | do_test view-1.1 { execsql { BEGIN; CREATE VIEW IF NOT EXISTS v1 AS SELECT a,b FROM t1; SELECT * FROM v1 ORDER BY a; } } {1 2 4 5 7 8} do_test view-1.1.100 { db config enable_view off catchsql { SELECT * FROM v1 ORDER BY a; } } {1 {access to view "v1" prohibited}} do_test view-1.1.110 { db config enable_view on catchsql { SELECT * FROM v1 ORDER BY a; } } {0 {1 2 4 5 7 8}} do_test view-1.2 { catchsql { ROLLBACK; SELECT * FROM v1 ORDER BY a; } } {1 {no such table: v1}} do_test view-1.3 { |
︙ | ︙ | |||
719 720 721 722 723 724 725 726 727 | WITH v17(x,y) AS (SELECT max(a), min(b) FROM t16 GROUP BY c) SELECT * FROM v17 AS one, v17 AS two WHERE one.x=1; } { 1 1 1 1 1 1 2 2 1 1 3 3 } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 | WITH v17(x,y) AS (SELECT max(a), min(b) FROM t16 GROUP BY c) SELECT * FROM v17 AS one, v17 AS two WHERE one.x=1; } { 1 1 1 1 1 1 2 2 1 1 3 3 } #------------------------------------------------------------------------- reset_db do_execsql_test view-27.0 { CREATE TABLE t0(c0 TEXT, c1); INSERT INTO t0(c0, c1) VALUES (-1, 0); CREATE VIEW v0(c0, c1) AS SELECT t0.c0, AVG(t0.c1) FROM t0; } do_execsql_test view-27.1 { SELECT c0, typeof(c0), c1, typeof(c1) FROM v0; } { -1 text 0.0 real } do_execsql_test view-27.2 { SELECT c0<c1 FROM v0 } 1 do_execsql_test view-27.3 { SELECT c1<c0 FROM v0 } 0 do_execsql_test view-27.4 { SELECT 1 FROM v0 WHERE c1<c0 } {} do_execsql_test view-27.5 { SELECT 1 FROM v0 WHERE c0<c1 } {1} do_execsql_test view-27.6 { SELECT c0<c1 FROM (SELECT t0.c0 AS c0, AVG(t0.c1) AS c1 FROM t0) } 1 do_execsql_test view-27.7 { SELECT c1<c0 FROM (SELECT t0.c0 AS c0, AVG(t0.c1) AS c1 FROM t0) } 0 do_execsql_test view-27.8 { SELECT 1 FROM (SELECT t0.c0 AS c0, AVG(t0.c1) AS c1 FROM t0) WHERE c1<c0 } {} do_execsql_test view-27.9 { SELECT 1 FROM (SELECT t0.c0 AS c0, AVG(t0.c1) AS c1 FROM t0) WHERE c0<c1 } {1} #------------------------------------------------------------------------- reset_db do_execsql_test view-28.0 { CREATE TABLE t0(c0 TEXT); CREATE VIEW v0(c0) AS SELECT t0.c0 FROM t0; INSERT INTO t0(c0) VALUES ('0'); } do_execsql_test view-28.1 { SELECT 0 IN (c0) FROM t0; } {0} do_execsql_test view-28.2 { SELECT 0 IN (c0) FROM (SELECT c0 FROM t0); } {0} finish_test |
Changes to test/vtab1.test.
︙ | ︙ | |||
870 871 872 873 874 875 876 877 878 879 880 881 882 883 | } } {31429} do_test vtab1.7-13 { execsql { SELECT rowid, a, b, c FROM real_abc } } {} ifcapable attach { do_test vtab1.8-1 { set echo_module "" execsql { ATTACH 'test2.db' AS aux; CREATE VIRTUAL TABLE aux.e2 USING echo(real_abc); | > > > > > > > > | 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 | } } {31429} do_test vtab1.7-13 { execsql { SELECT rowid, a, b, c FROM real_abc } } {} # PRAGMA index_info and index_xinfo are no-ops on a virtual table do_test vtab1.7-14 { execsql { PRAGMA index_info('echo_abc'); PRAGMA index_xinfo('echo_abc'); } } {} ifcapable attach { do_test vtab1.8-1 { set echo_module "" execsql { ATTACH 'test2.db' AS aux; CREATE VIRTUAL TABLE aux.e2 USING echo(real_abc); |
︙ | ︙ | |||
1299 1300 1301 1302 1303 1304 1305 | INSERT INTO t6 VALUES(3, '8James'); INSERT INTO t6 VALUES(4, '8John'); INSERT INTO t6 VALUES(5, 'Phillip'); INSERT INTO t6 VALUES(6, 'Bartholomew'); CREATE VIRTUAL TABLE e6 USING echo(t6); } | > | | | | | | | | | | | | | | | | | | | > | | | 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 | INSERT INTO t6 VALUES(3, '8James'); INSERT INTO t6 VALUES(4, '8John'); INSERT INTO t6 VALUES(5, 'Phillip'); INSERT INTO t6 VALUES(6, 'Bartholomew'); CREATE VIRTUAL TABLE e6 USING echo(t6); } ifcapable !icu { foreach {tn sql res filter} { 1.1 "SELECT a FROM e6 WHERE b>'8James'" {4 2 6 1 5} {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} 8James} 1.2 "SELECT a FROM e6 WHERE b>='8' AND b<'9'" {3 4} {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} 8 9} 1.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4} {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8J%} 1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4} {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8j%} 1.5 "SELECT a FROM e6 WHERE b LIKE '8%'" {3 4} {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8%} } { set echo_module {} do_execsql_test 18.$tn.1 $sql $res do_test 18.$tn.2 { lrange $::echo_module 2 end } $filter } } do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON } foreach {tn sql res filter} { 2.1 "SELECT a FROM e6 WHERE b LIKE '8%'" {3 4} {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8%} 2.2 "SELECT a FROM e6 WHERE b LIKE '8j%'" {} {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8j 8k 8j%} 2.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4} {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8K 8J%} } { set echo_module {} do_execsql_test 18.$tn.1 $sql $res do_test 18.$tn.2 { lrange $::echo_module 2 end } $filter } do_execsql_test 18.2.x { PRAGMA case_sensitive_like = OFF } #------------------------------------------------------------------------- # Test that it is ok to override and existing module. # do_test 19.1 { sqlite3 db2 test.db register_echo_module [sqlite3_connection_pointer db2] } SQLITE_OK do_test 19.2 { register_echo_module [sqlite3_connection_pointer db2] } SQLITE_OK do_test 19.3 { db2 close } {} #------------------------------------------------------------------------- # Test that the bug fixed by [b0c1ba655d69] really is fixed. # |
︙ | ︙ |
Changes to test/vtabH.test.
︙ | ︙ | |||
26 27 28 29 30 31 32 | do_execsql_test 1.0 { CREATE TABLE t6(a, b TEXT); CREATE INDEX i6 ON t6(b, a); CREATE VIRTUAL TABLE e6 USING echo(t6); } | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | do_execsql_test 1.0 { CREATE TABLE t6(a, b TEXT); CREATE INDEX i6 ON t6(b, a); CREATE VIRTUAL TABLE e6 USING echo(t6); } ifcapable !icu { foreach {tn sql expect} { 1 "SELECT * FROM e6 WHERE b LIKE '8abc'" { xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8ABC 8abd 8abc } 2 "SELECT * FROM e6 WHERE b GLOB '8abc'" { xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?} xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?} 8abc 8abd 8abc } 3 "SELECT * FROM e6 WHERE b LIKE '8e/'" { xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?} xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8e/ } 4 "SELECT * FROM e6 WHERE b GLOB '8e/'" { xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?} xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8e/ } } { do_test 1.$tn { set echo_module {} execsql $sql set ::echo_module } [list {*}$expect] } } #-------------------------------------------------------------------------- register_tclvar_module db set ::xyz 10 |
︙ | ︙ |
Changes to test/walvfs.test.
︙ | ︙ | |||
422 423 424 425 426 427 428 | catchsql { SELECT count(*) FROM t1 } db2 } {1 {disk I/O error}} db close db2 close tvfs delete finish_test | < | 422 423 424 425 426 427 428 | catchsql { SELECT count(*) FROM t1 } db2 } {1 {disk I/O error}} db close db2 close tvfs delete finish_test |
Changes to test/wapptest.tcl.
1 2 3 4 5 6 7 | #!/bin/sh # \ exec wapptclsh "$0" ${1+"$@"} # package required wapp source [file join [file dirname [info script]] wapp.tcl] | < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/bin/sh # \ exec wapptclsh "$0" ${1+"$@"} # package required wapp source [file join [file dirname [info script]] wapp.tcl] # Variables set by the "control" form: # # G(platform) - User selected platform. # G(test) - Set to "Normal", "Veryquick", "Smoketest" or "Build-Only". # G(keep) - Boolean. True to delete no files after each test. # G(msvc) - Boolean. True to use MSVC as the compiler. # G(tcl) - Use Tcl from this directory for builds. |
︙ | ︙ | |||
64 65 66 67 68 69 70 71 72 73 74 75 76 77 | foreach t $G(test_array) { set config [dict get $t config] set target [dict get $t target] wapptest_output [format " %-25s%s" $config $target] } wapptest_output [string repeat * 70] } # Generate the text for the box at the top of the UI. The current SQLite # version, according to fossil, along with a warning if there are # uncommitted changes in the checkout. # proc generate_fossil_info {} { global G | > > > > > > > > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | foreach t $G(test_array) { set config [dict get $t config] set target [dict get $t target] wapptest_output [format " %-25s%s" $config $target] } wapptest_output [string repeat * 70] } proc releasetest_data {args} { global G set rtd [file join $G(srcdir) test releasetest_data.tcl] set fd [open "|[info nameofexecutable] $rtd $args" r+] set ret [read $fd] close $fd return $ret } # Generate the text for the box at the top of the UI. The current SQLite # version, according to fossil, along with a warning if there are # uncommitted changes in the checkout. # proc generate_fossil_info {} { global G |
︙ | ︙ | |||
104 105 106 107 108 109 110 | # app is in some other state ("running" or "stopped"), this command # is a no-op. # proc set_test_array {} { global G if { $G(state)=="config" } { set G(test_array) [list] | > > | | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | # app is in some other state ("running" or "stopped"), this command # is a no-op. # proc set_test_array {} { global G if { $G(state)=="config" } { set G(test_array) [list] set debug "-debug" if {$G(debug)==0} { set debug "-nodebug"} foreach {config target} [releasetest_data tests $debug $G(platform)] { # If using MSVC, do not run sanitize or valgrind tests. Or the # checksymbols test. if {$G(msvc) && ( "Sanitize" == $config || "checksymbols" in $target || "valgrindtest" in $target |
︙ | ︙ | |||
132 133 134 135 136 137 138 | set target testfixture.exe } } } } lappend G(test_array) [dict create config $config target $target] | < < < < < < < < < < < < < < < < | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | set target testfixture.exe } } } } lappend G(test_array) [dict create config $config target $target] } } } proc count_tests_and_errors {name logfile} { global G |
︙ | ︙ | |||
309 310 311 312 313 314 315 | if {[string trim $line] != ""} { puts "Trace : $name - \"$line\"" } } do_some_stuff } # Return the contents of the "slave script" - the script run by slave | | | < < < < < < < < < < < < < | > | < | < < | | < | > > | | | | < < | < < | < > > | | | < | | < < < < < < < < < < | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | if {[string trim $line] != ""} { puts "Trace : $name - \"$line\"" } } do_some_stuff } # Return the contents of the "slave script" - the script run by slave # processes to actually perform the test. All it does is execute the # test script already written to disk (wapptest_cmd.sh or wapptest_cmd.bat). # proc wapptest_slave_script {} { global G if {$G(msvc)==0} { set dir [file join .. $G(srcdir)] set res [subst -nocommands { set rc [catch "exec sh wapptest_cmd.sh {$dir} >>& test.log" ] exit [set rc] }] } else { set dir [file nativename [file normalize $G(srcdir)]] set dir [string map [list "\\" "\\\\"] $dir] set res [subst -nocommands { set rc [catch "exec wapptest_cmd.bat {$dir} >>& test.log" ] exit [set rc] }] } set res } # Launch a slave process to run a test. # proc slave_launch {name target dir} { global G catch { file mkdir $dir } msg foreach f [glob -nocomplain [file join $dir *]] { catch { file delete -force $f } } set G(test.$name.dir) $dir # Write the test command to wapptest_cmd.sh|bat. # set ext sh if {$G(msvc)} { set ext bat } set fd1 [open [file join $dir wapptest_cmd.$ext] w] if {$G(msvc)} { puts $fd1 [releasetest_data script -msvc $name $target] } else { puts $fd1 [releasetest_data script $name $target] } close $fd1 # Write the wapptest_run.tcl script to the test directory. To run the # commands in the other two files. # set fd3 [open [file join $dir wapptest_run.tcl] w] puts $fd3 [wapptest_slave_script] close $fd3 |
︙ | ︙ | |||
444 445 446 447 448 449 450 451 | if {$nLaunch<=0} break set name [dict get $j config] if { ![info exists G(test.$name.channel)] && ![info exists G(test.$name.done)] } { set target [dict get $j target] set G(test.$name.start) [clock seconds] | > < < | < < < < < < < < < < | < < < < < < | < | 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 | if {$nLaunch<=0} break set name [dict get $j config] if { ![info exists G(test.$name.channel)] && ![info exists G(test.$name.done)] } { set target [dict get $j target] set dir [string tolower [string map {" " _ "-" _} $name]] set G(test.$name.start) [clock seconds] set G(test.$name.log) [file join $dir test.log] slave_launch $name $target $dir incr nLaunch -1 } } } } proc generate_select_widget {label id lOpt opt} { |
︙ | ︙ | |||
513 514 515 516 517 518 519 | wapp-trim { </div> <div class="border" id=controls> <form action="control" method="post" name="control"> } # Build the "platform" select widget. | | | 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | wapp-trim { </div> <div class="border" id=controls> <form action="control" method="post" name="control"> } # Build the "platform" select widget. set lOpt [releasetest_data platforms] generate_select_widget Platform control_platform $lOpt $G(platform) # Build the "test" select widget. set lOpt [list Normal Veryquick Smoketest Build-Only] generate_select_widget Test control_test $lOpt $G(test) # Build the "jobs" select widget. Options are 1 to 8. |
︙ | ︙ | |||
882 883 884 885 886 887 888 | for {set i 0} {$i < [llength $lTestArg]} {incr i} { switch -- [lindex $lTestArg $i] { -platform { if {$i==[llength $lTestArg]-1} { wapptest_usage } incr i set arg [lindex $lTestArg $i] | | | 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 | for {set i 0} {$i < [llength $lTestArg]} {incr i} { switch -- [lindex $lTestArg $i] { -platform { if {$i==[llength $lTestArg]-1} { wapptest_usage } incr i set arg [lindex $lTestArg $i] set lPlatform [releasetest_data platforms] if {[lsearch $lPlatform $arg]<0} { puts stderr "No such platform: $arg. Platforms are: $lPlatform" exit -1 } set G(platform) $arg } |
︙ | ︙ |
Changes to test/where.test.
︙ | ︙ | |||
1534 1535 1536 1537 1538 1539 1540 | SELECT * FROM t1 WHERE c='iii' } {0 {}} do_catchsql_test where-25.5 { INSERT INTO t1 VALUES(4, 'four', 'iii') ON CONFLICT(c) DO UPDATE SET b=NULL } {1 {corrupt database}} | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 | SELECT * FROM t1 WHERE c='iii' } {0 {}} do_catchsql_test where-25.5 { INSERT INTO t1 VALUES(4, 'four', 'iii') ON CONFLICT(c) DO UPDATE SET b=NULL } {1 {corrupt database}} # 2019-08-21 Ticket https://www.sqlite.org/src/info/d9f584e936c7a8d0 # db close sqlite3 db :memory: do_execsql_test where-26.1 { CREATE TABLE t0(c0 INTEGER PRIMARY KEY, c1 TEXT); INSERT INTO t0(c0, c1) VALUES (1, 'a'); CREATE TABLE t1(c0 INT PRIMARY KEY, c1 TEXT); INSERT INTO t1(c0, c1) VALUES (1, 'a'); SELECT * FROM t0 WHERE '-1' BETWEEN 0 AND t0.c0; } {1 a} do_execsql_test where-26.2 { SELECT * FROM t1 WHERE '-1' BETWEEN 0 AND t1.c0; } {1 a} do_execsql_test where-26.3 { SELECT * FROM t0 WHERE '-1'>=0 AND '-1'<=t0.c0; } {1 a} do_execsql_test where-26.4 { SELECT * FROM t1 WHERE '-1'>=0 AND '-1'<=t1.c0; } {1 a} do_execsql_test where-26.5 { SELECT '-1' BETWEEN 0 AND t0.c0 FROM t0; } {1} do_execsql_test where-26.6 { SELECT '-1' BETWEEN 0 AND t1.c0 FROM t1; } {1} do_execsql_test where-26.7 { SELECT '-1'>=0 AND '-1'<=t0.c0 FROM t0; } {1} do_execsql_test where-26.8 { SELECT '-1'>=0 AND '-1'<=t1.c0 FROM t1; } {1} finish_test |
Changes to test/where9.test.
︙ | ︙ | |||
783 784 785 786 787 788 789 | WHERE (+b IS NULL AND c NOT NULL AND d NOT NULL) OR (b NOT NULL AND c IS NULL AND d NOT NULL) OR (b NOT NULL AND c NOT NULL AND d IS NULL) } } {1 {no query solution}} set solution_possible 0 | | | 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 | WHERE (+b IS NULL AND c NOT NULL AND d NOT NULL) OR (b NOT NULL AND c IS NULL AND d NOT NULL) OR (b NOT NULL AND c NOT NULL AND d IS NULL) } } {1 {no query solution}} set solution_possible 0 ifcapable stat4 { if {[permutation] != "no_optimization"} { set solution_possible 1 } } if $solution_possible { # When STAT3 is enabled, the "b NOT NULL" terms get translated # into b>NULL, which can be satified by the index t1b. It is a very # expensive way to do the query, but it works, and so a solution is possible. do_test where9-6.8.3-stat4 { |
︙ | ︙ | |||
856 857 858 859 860 861 862 | CREATE INDEX t5ye ON t5(y, e); CREATE INDEX t5yf ON t5(y, f); CREATE INDEX t5yg ON t5(y, g); CREATE TABLE t6(a, b, c, e, d, f, g, x, y); INSERT INTO t6 SELECT * FROM t5; ANALYZE t5; } | < < < < < | 856 857 858 859 860 861 862 863 864 865 866 867 868 869 | CREATE INDEX t5ye ON t5(y, e); CREATE INDEX t5yf ON t5(y, f); CREATE INDEX t5yg ON t5(y, g); CREATE TABLE t6(a, b, c, e, d, f, g, x, y); INSERT INTO t6 SELECT * FROM t5; ANALYZE t5; } } {} do_test where9-7.1.1 { count_steps { SELECT a FROM t5 WHERE x='y' AND (b=913 OR c=27027) ORDER BY a; } } {79 81 83 scan 0 sort 1} do_test where9-7.1.2 { |
︙ | ︙ |
Changes to test/whereG.test.
︙ | ︙ | |||
261 262 263 264 265 266 267 268 269 270 | } {1 3 1 4 9 3 9 4} do_execsql_test 7.2 { SELECT likelihood(a,0.5), x FROM t1, t2 ORDER BY 1, 2; } {1 3 1 4 9 3 9 4} do_execsql_test 7.3 { SELECT coalesce(a,a), x FROM t1, t2 ORDER BY 1, 2; } {1 3 1 4 9 3 9 4} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | } {1 3 1 4 9 3 9 4} do_execsql_test 7.2 { SELECT likelihood(a,0.5), x FROM t1, t2 ORDER BY 1, 2; } {1 3 1 4 9 3 9 4} do_execsql_test 7.3 { SELECT coalesce(a,a), x FROM t1, t2 ORDER BY 1, 2; } {1 3 1 4 9 3 9 4} # 2019-08-22 # Ticket https://www.sqlite.org/src/info/7e07a3dbf5a8cd26 # do_execsql_test 8.1 { DROP TABLE IF EXISTS t0; CREATE TABLE t0 (c0); INSERT INTO t0(c0) VALUES ('a'); SELECT LIKELY(t0.rowid) <= '0' FROM t0; } {1} do_execsql_test 8.2 { SELECT * FROM t0 WHERE LIKELY(t0.rowid) <= '0'; } {a} do_execsql_test 8.3 { SELECT (t0.rowid) <= '0' FROM t0; } {0} do_execsql_test 8.4 { SELECT * FROM t0 WHERE (t0.rowid) <= '0'; } {} do_execsql_test 8.5 { SELECT unlikely(t0.rowid) <= '0', likelihood(t0.rowid,0.5) <= '0' FROM t0; } {1 1} do_execsql_test 8.6 { SELECT * FROM t0 WHERE unlikely(t0.rowid) <= '0'; } {a} do_execsql_test 8.7 { SELECT * FROM t0 WHERE likelihood(t0.rowid, 0.5) <= '0'; } {a} do_execsql_test 8.8 { SELECT unlikely(t0.rowid <= '0'), likely(t0.rowid <= '0'), likelihood(t0.rowid <= '0',0.5) FROM t0; } {0 0 0} do_execsql_test 8.9 { SELECT * FROM t0 WHERE unlikely(t0.rowid <= '0'); } {} do_execsql_test 8.10 { SELECT * FROM t0 WHERE likelihood(t0.rowid <= '0', 0.5); } {} finish_test |
Deleted test/wild001.test.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to test/window1.test.
︙ | ︙ | |||
253 254 255 256 257 258 259 260 261 262 263 264 265 266 | } {1 {no such column: x}} do_catchsql_test 7.1.6 { SELECT trim(x) OVER (ORDER BY y) FROM t1; } {1 {trim() may not be used as a window function}} do_catchsql_test 7.1.7 { SELECT max(x) OVER abc FROM t1 WINDOW def AS (ORDER BY y); } {1 {no such window: abc}} do_execsql_test 7.2 { SELECT lead(y) OVER win, lead(y, 2) OVER win, lead(y, 3, 'default') OVER win FROM t1 | > > > | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | } {1 {no such column: x}} do_catchsql_test 7.1.6 { SELECT trim(x) OVER (ORDER BY y) FROM t1; } {1 {trim() may not be used as a window function}} do_catchsql_test 7.1.7 { SELECT max(x) OVER abc FROM t1 WINDOW def AS (ORDER BY y); } {1 {no such window: abc}} do_catchsql_test 7.1.8 { SELECT row_number(x) OVER () FROM t1 } {1 {wrong number of arguments to function row_number()}} do_execsql_test 7.2 { SELECT lead(y) OVER win, lead(y, 2) OVER win, lead(y, 3, 'default') OVER win FROM t1 |
︙ | ︙ | |||
1163 1164 1165 1166 1167 1168 1169 | 13 M cc NULL JM | 3 C cc 1 {} | 4 D cc 8.25 {} | 12 L cc 'xyZ' L | 11 K cc 'xyz' K | } | < > > > > > | > > > > > > > > > > > > > > | 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 | 13 M cc NULL JM | 3 C cc 1 {} | 4 D cc 8.25 {} | 12 L cc 'xyZ' L | 11 K cc 'xyz' K | } # 2019-07-18 # Check-in [7ef7b23cbb1b9ace] (which was itself a fix for ticket # https://www.sqlite.org/src/info/1be72aab9) introduced a new problem # if the LHS of a BETWEEN operator is a WINDOW function. The problem # was found by (the recently enhanced) dbsqlfuzz. # do_execsql_test 30.0 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES('BB','aa',399); SELECT count () OVER win1 NOT BETWEEN 'a' AND 'mmm', count () OVER win3 FROM t1 WINDOW win1 AS (ORDER BY a GROUPS BETWEEN 4 PRECEDING AND 1 FOLLOWING EXCLUDE CURRENT ROW), win2 AS (PARTITION BY b ORDER BY a), win3 AS (win2 RANGE BETWEEN 5.2 PRECEDING AND true PRECEDING ); } {1 1} finish_test |
Changes to test/window2.tcl.
︙ | ︙ | |||
420 421 422 423 424 425 426 427 428 429 430 431 | execsql_float_test 4.9 { SELECT rank() OVER win AS rank, cume_dist() OVER win AS cume_dist FROM t1 WINDOW win AS (ORDER BY 1); } finish_test | > > > > > > > | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | execsql_float_test 4.9 { SELECT rank() OVER win AS rank, cume_dist() OVER win AS cume_dist FROM t1 WINDOW win AS (ORDER BY 1); } execsql_test 4.10 { SELECT count(*) OVER (ORDER BY b) FROM t1 } execsql_test 4.11 { SELECT count(distinct a) FILTER (WHERE b='odd') FROM t1 } finish_test |
Changes to test/window2.test.
︙ | ︙ | |||
888 889 890 891 892 893 894 895 896 | if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { error "list element [set i] does not match: got=[set r] expected=[set r2]" } incr i } set {} {} } {} finish_test | > > > > > > > > | 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 | if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { error "list element [set i] does not match: got=[set r] expected=[set r2]" } incr i } set {} {} } {} do_execsql_test 4.10 { SELECT count(*) OVER (ORDER BY b) FROM t1 } {3 3 3 6 6 6} do_execsql_test 4.11 { SELECT count(distinct a) FILTER (WHERE b='odd') FROM t1 } {3} finish_test |
Changes to test/window4.tcl.
︙ | ︙ | |||
381 382 383 384 385 386 387 388 389 390 | execsql_test 11.4 { SELECT * FROM ( SELECT NTILE(256) OVER (ORDER BY total) - 1 AS nt FROM t8 ) sub; } finish_test | > > > > > > > > > > > > > > > > > > > > | 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | execsql_test 11.4 { SELECT * FROM ( SELECT NTILE(256) OVER (ORDER BY total) - 1 AS nt FROM t8 ) sub; } execsql_test 12.0 { DROP TABLE IF EXISTS t2; CREATE TABLE t2(a INTEGER); INSERT INTO t2 VALUES(1), (2), (3); } execsql_test 12.1 { SELECT (SELECT min(a) OVER ()) FROM t2 } execsql_float_test 12.2 { SELECT (SELECT avg(a)) FROM t2 ORDER BY 1 } execsql_float_test 12.3 { SELECT (SELECT avg(a) UNION SELECT min(a) OVER ()) FROM t2 GROUP BY a ORDER BY 1 } finish_test |
Changes to test/window4.test.
︙ | ︙ | |||
1319 1320 1321 1322 1323 1324 1325 1326 1327 | } {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 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 | } {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} do_execsql_test 12.0 { DROP TABLE IF EXISTS t2; CREATE TABLE t2(a INTEGER); INSERT INTO t2 VALUES(1), (2), (3); } {} do_execsql_test 12.1 { SELECT (SELECT min(a) OVER ()) FROM t2 } {1 2 3} do_test 12.2 { set myres {} foreach r [db eval {SELECT (SELECT avg(a)) FROM t2 ORDER BY 1}] { lappend myres [format %.4f [set r]] } set res2 {2.0000} set i 0 foreach r [set myres] r2 [set res2] { if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { error "list element [set i] does not match: got=[set r] expected=[set r2]" } incr i } set {} {} } {} do_test 12.3 { set myres {} foreach r [db eval {SELECT (SELECT avg(a) UNION SELECT min(a) OVER ()) FROM t2 GROUP BY a ORDER BY 1}] { lappend myres [format %.4f [set r]] } set res2 {1.0000 2.0000 3.0000} set i 0 foreach r [set myres] r2 [set res2] { if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { error "list element [set i] does not match: got=[set r] expected=[set r2]" } incr i } set {} {} } {} finish_test |
Changes to test/window6.test.
︙ | ︙ | |||
364 365 366 367 368 369 370 | } { fifteen fifteen ten fifteen.ten thirty fifteen.ten.thirty } finish_test | < | 364 365 366 367 368 369 370 | } { fifteen fifteen ten fifteen.ten thirty fifteen.ten.thirty } finish_test |
Changes to test/window7.test.
︙ | ︙ | |||
37 38 39 40 41 42 43 | (1, 81), (2, 82), (3, 83), (4, 84), (5, 85), (6, 86), (7, 87), (8, 88), (9, 89), (0, 90), (1, 91), (2, 92), (3, 93), (4, 94), (5, 95), (6, 96), (7, 97), (8, 98), (9, 99), (0, 100); } {} do_execsql_test 1.1 { SELECT a, sum(b) FROM t3 GROUP BY a ORDER BY 1; | | > | > > > > > > > > > > > | > > > > > > > > > > > | > > > > > > > > > > > > | > > > > > > > > > > > | > > > > > > > > > > > > | > > > > > > > > > > > > | > > > > > > > > > > > | > > > > > > > > > > > | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 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 | (1, 81), (2, 82), (3, 83), (4, 84), (5, 85), (6, 86), (7, 87), (8, 88), (9, 89), (0, 90), (1, 91), (2, 92), (3, 93), (4, 94), (5, 95), (6, 96), (7, 97), (8, 98), (9, 99), (0, 100); } {} do_execsql_test 1.1 { SELECT a, sum(b) FROM t3 GROUP BY a ORDER BY 1; } {0 550 1 460 2 470 3 480 4 490 5 500 6 510 7 520 8 530 9 540} do_execsql_test 1.2 { SELECT a, sum(b) OVER ( ORDER BY a GROUPS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t3 ORDER BY 1; } {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540} do_execsql_test 1.3 { SELECT a, sum(b) OVER ( ORDER BY a GROUPS BETWEEN 0 PRECEDING AND 0 FOLLOWING ) FROM t3 ORDER BY 1; } {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540} do_execsql_test 1.4 { SELECT a, sum(b) OVER ( ORDER BY a GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING ) FROM t3 ORDER BY 1; } {0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590} do_execsql_test 1.5 { SELECT a, sum(b) OVER ( ORDER BY a RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING ) FROM t3 ORDER BY 1; } {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540} do_execsql_test 1.6 { SELECT a, sum(b) OVER ( ORDER BY a RANGE BETWEEN 2 PRECEDING AND 2 FOLLOWING ) FROM t3 ORDER BY 1; } {0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590} do_execsql_test 1.7 { SELECT a, sum(b) OVER ( ORDER BY a RANGE BETWEEN 2 PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1; } {0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 1 1480 1 1480 1 1480 1 1480 1 1480 1 1480 1 1480 1 1480 1 1480 1 1480 2 1960 2 1960 2 1960 2 1960 2 1960 2 1960 2 1960 2 1960 2 1960 2 1960 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 5 1980 5 1980 5 1980 5 1980 5 1980 5 1980 5 1980 5 1980 5 1980 5 1980 6 2020 6 2020 6 2020 6 2020 6 2020 6 2020 6 2020 6 2020 6 2020 6 2020 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590} do_execsql_test 1.8.1 { SELECT a, sum(b) OVER ( ORDER BY a RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1; } {0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 1 930 1 930 1 930 1 930 1 930 1 930 1 930 1 930 1 930 1 930 2 950 2 950 2 950 2 950 2 950 2 950 2 950 2 950 2 950 2 950 3 970 3 970 3 970 3 970 3 970 3 970 3 970 3 970 3 970 3 970 4 990 4 990 4 990 4 990 4 990 4 990 4 990 4 990 4 990 4 990 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 8 1070 8 1070 8 1070 8 1070 8 1070 8 1070 8 1070 8 1070 8 1070 8 1070 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540} do_execsql_test 1.8.2 { SELECT a, sum(b) OVER ( ORDER BY a DESC RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1; } {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 2 930 2 930 2 930 2 930 2 930 2 930 2 930 2 930 2 930 2 930 3 950 3 950 3 950 3 950 3 950 3 950 3 950 3 950 3 950 3 950 4 970 4 970 4 970 4 970 4 970 4 970 4 970 4 970 4 970 4 970 5 990 5 990 5 990 5 990 5 990 5 990 5 990 5 990 5 990 5 990 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 8 1050 8 1050 8 1050 8 1050 8 1050 8 1050 8 1050 8 1050 8 1050 8 1050 9 1070 9 1070 9 1070 9 1070 9 1070 9 1070 9 1070 9 1070 9 1070 9 1070} finish_test |
Changes to test/window8.tcl.
︙ | ︙ | |||
193 194 195 196 197 198 199 | } execsql_test 4.2.1 { SELECT sum(b) OVER ( ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } | > > > > | > | > > > > > > > > > > > > > > | > | > > > > > > > > > > > > > > > > > | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | } execsql_test 4.2.1 { SELECT sum(b) OVER ( ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } execsql_test 4.2.2 { SELECT sum(b) OVER ( ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } execsql_test 4.2.3 { SELECT sum(b) OVER ( ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } execsql_test 4.2.4 { SELECT sum(b) OVER ( ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } execsql_test 4.3.1 { SELECT sum(b) OVER ( ORDER BY a NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } execsql_test 4.3.2 { SELECT sum(b) OVER ( ORDER BY a NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } execsql_test 4.4.1 { SELECT sum(b) OVER ( ORDER BY a NULLS FIRST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } execsql_test 4.4.2 { SELECT sum(b) OVER ( ORDER BY a NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } execsql_test 4.4.3 { SELECT sum(b) OVER ( ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } execsql_test 4.4.4 { SELECT sum(b) OVER ( ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } execsql_test 4.5.1 { SELECT sum(b) OVER ( ORDER BY a ASC NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } execsql_test 4.5.2 { SELECT sum(b) OVER ( ORDER BY a DESC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } ========== execsql_test 5.0 { INSERT INTO t3 VALUES (NULL, 'bb', 355), (NULL, 'cc', 158), (NULL, 'aa', 399), ('JJ', NULL, 839), ('FF', NULL, 618), ('BB', NULL, 393), |
︙ | ︙ | |||
244 245 246 247 248 249 250 251 252 253 254 255 256 257 | 3 { PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING } 4 { ORDER BY a NULLS FIRST GROUPS 6 PRECEDING } 5 { ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING } 6 { ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING } 7 { ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING } } { execsql_test 5.$tn.$tn2.1 " SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( $frame $ex ) | > > > > > > > > > > > | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | 3 { PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING } 4 { ORDER BY a NULLS FIRST GROUPS 6 PRECEDING } 5 { ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING } 6 { ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING } 7 { ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING } 8 { RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING } 9 { ORDER BY a NULLS LAST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING } 10 { PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING } 11 { ORDER BY a NULLS LAST GROUPS 6 PRECEDING } 12 { ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING } 13 { ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING } 14 { ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING } } { execsql_test 5.$tn.$tn2.1 " SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( $frame $ex ) |
︙ | ︙ | |||
288 289 290 291 292 293 294 295 296 297 298 299 | execsql_test 6.2 { SELECT string_agg(a, '.') OVER ( ORDER BY b DESC NULLS LAST RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING ) FROM t2 } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 | execsql_test 6.2 { SELECT string_agg(a, '.') OVER ( ORDER BY b DESC NULLS LAST RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING ) FROM t2 } ========== execsql_test 7.0 { DROP TABLE IF EXISTS t2; CREATE TABLE t2(a INTEGER, b INTEGER); INSERT INTO t2 VALUES(1, 65); INSERT INTO t2 VALUES(2, NULL); INSERT INTO t2 VALUES(3, NULL); INSERT INTO t2 VALUES(4, NULL); INSERT INTO t2 VALUES(5, 66); INSERT INTO t2 VALUES(6, 67); } foreach {tn f ex} { 1 sum "" 2 min "" 3 sum "EXCLUDE CURRENT ROW" 4 max "EXCLUDE CURRENT ROW" } { execsql_test 7.$tn.1 " SELECT $f (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING ); " execsql_test 7.$tn.2 " SELECT $f (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING ); " execsql_test 7.$tn.3 " SELECT $f (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING ); " execsql_test 7.$tn.4 " SELECT $f (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING ); " execsql_test 7.$tn.5 " SELECT $f (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING ); " execsql_test 7.$tn.6 " SELECT $f (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING ); " execsql_test 7.$tn.7 " SELECT $f (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING ); " execsql_test 7.$tn.8 " SELECT $f (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING ); " execsql_test 7.$tn.9 " SELECT $f (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING ); " } finish_test |
Changes to test/window8.test.
︙ | ︙ | |||
3518 3519 3520 3521 3522 3523 3524 | ORDER BY a DESC RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING ) FROM t1 ORDER BY 1; } {6 6 6 9 9} do_execsql_test 4.2.1 { SELECT sum(b) OVER ( ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING | | > > > > > > | > > > > > > | | > > > > > > | | | | > > > > > > > > > > > > > > > > > > > > > > > > > | | 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 | ORDER BY a DESC RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING ) FROM t1 ORDER BY 1; } {6 6 6 9 9} do_execsql_test 4.2.1 { SELECT sum(b) OVER ( ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } {{} {} 6 6 6} do_execsql_test 4.2.2 { SELECT sum(b) OVER ( ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } {6 6 6 {} {}} do_execsql_test 4.2.3 { SELECT sum(b) OVER ( ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } {{} {} 6 6 6} do_execsql_test 4.2.4 { SELECT sum(b) OVER ( ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } {6 6 6 {} {}} do_execsql_test 4.3.1 { SELECT sum(b) OVER ( ORDER BY a NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } {6 6 6 15 15} do_execsql_test 4.3.2 { SELECT sum(b) OVER ( ORDER BY a NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } {9 9 15 15 15} do_execsql_test 4.4.1 { SELECT sum(b) OVER ( ORDER BY a NULLS FIRST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } {3 6 9 9 12} do_execsql_test 4.4.2 { SELECT sum(b) OVER ( ORDER BY a NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } {5 6 8 9 10} do_execsql_test 4.4.3 { SELECT sum(b) OVER ( ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } {5 6 8 9 10} do_execsql_test 4.4.4 { SELECT sum(b) OVER ( ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } {5 6 8 9 10} do_execsql_test 4.5.1 { SELECT sum(b) OVER ( ORDER BY a ASC NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } {9 9 15 15 15} do_execsql_test 4.5.2 { SELECT sum(b) OVER ( ORDER BY a DESC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS LAST; } {6 6 6 15 15} #========================================================================== do_execsql_test 5.0 { INSERT INTO t3 VALUES (NULL, 'bb', 355), (NULL, 'cc', 158), (NULL, 'aa', 399), ('JJ', NULL, 839), ('FF', NULL, 618), ('BB', NULL, 393), (NULL, 'bb', 629), (NULL, NULL, 667), (NULL, NULL, 870); } {} do_execsql_test 5.1.1.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 |
︙ | ︙ | |||
3583 3584 3585 3586 3587 3588 3589 | do_execsql_test 5.1.1.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) | | | 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 | do_execsql_test 5.1.1.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 |
︙ | ︙ | |||
3605 3606 3607 3608 3609 3610 3611 | 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1} do_execsql_test 5.1.2.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 | | | | 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 | 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1} do_execsql_test 5.1.2.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 62 979 102 62 979 102 62 |
︙ | ︙ | |||
3629 3630 3631 3632 3633 3634 3635 | 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33} do_execsql_test 5.1.2.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 | 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33} do_execsql_test 5.1.2.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 5287 74 10 5287 74 10 5287 74 10 5287 74 10 5287 74 10 5287 74 10 5287 74 10 8400 65 9 8400 65 9 8400 65 9 8400 65 9 8400 65 9 8400 65 9 8400 65 9 8400 65 9 8400 65 9 9664 57 8 9664 57 8 9664 57 8 9664 57 8 9664 57 8 9664 57 8 9664 57 8 9664 57 8 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7 |
︙ | ︙ | |||
3655 3656 3657 3658 3659 3660 3661 | do_execsql_test 5.1.3.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) | | | 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 | do_execsql_test 5.1.3.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {777 113 5 777 113 5 777 113 5 777 113 5 777 113 5 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 822 158 6 822 158 6 822 158 6 822 158 6 822 158 6 822 158 6 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 |
︙ | ︙ | |||
3679 3680 3681 3682 3683 3684 3685 | do_execsql_test 5.1.3.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) | | | | | 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 | do_execsql_test 5.1.3.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1366 1 1 1366 1 1 1366 1 1 1366 1 1 1366 1 1 1366 1 1 1519 1 1 1519 1 1 1519 1 1 1519 1 1 1519 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1} do_execsql_test 5.1.4.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 |
︙ | ︙ | |||
3722 3723 3724 3725 3726 3727 3728 | 979 102 59 979 102 59 979 102 59 979 102 59 979 102 59} do_execsql_test 5.1.4.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 | 979 102 59 979 102 59 979 102 59 979 102 59 979 102 59} do_execsql_test 5.1.4.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 4359 7 2 4359 7 2 4359 7 2 4359 7 2 4359 7 2 4359 7 2 4359 7 2 4359 7 2 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 9206 28 4 9206 28 4 9206 28 4 9206 28 4 9206 28 4 9206 28 4 11010 34 5 11010 34 5 11010 34 5 11010 34 5 11010 34 5 11010 34 5 11010 34 5 12368 74 10 12368 74 10 12368 74 10 |
︙ | ︙ | |||
3746 3747 3748 3749 3750 3751 3752 | 13949 81 11} do_execsql_test 5.1.5.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 | | | | 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 | 13949 81 11} do_execsql_test 5.1.5.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 2 113 113 2 133 133 1 148 148 1 160 158 2 160 158 2 160 158 2 208 208 1 224 223 2 224 223 2 239 234 3 239 234 3 239 234 3 252 247 3 257 247 5 257 247 5 257 250 4 257 252 3 295 295 1 309 309 1 336 330 3 336 330 3 336 330 3 346 346 1 355 354 2 355 354 2 355 354 2 399 393 4 399 393 4 399 393 4 399 393 4 399 393 4 412 412 1 421 421 1 430 430 1 443 443 1 480 480 2 480 480 2 574 572 2 574 572 2 607 607 1 |
︙ | ︙ | |||
3769 3770 3771 3772 3773 3774 3775 | 938 934 3 938 934 3 963 959 2 963 959 2 979 979 1} do_execsql_test 5.1.5.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | | | 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 | 938 934 3 938 934 3 963 959 2 963 959 2 979 979 1} do_execsql_test 5.1.5.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 25 23 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 {} 50 42 {} 60 51 {} 61 52 {} 64 55 {} 64 55 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 85 72 {} 85 72 133 4 3 223 10 8 223 11 9 226 2 2 226 2 2 239 12 10 239 13 11 239 14 12 247 15 13 257 18 16 257 19 17 295 20 18 309 21 19 335 22 20 335 23 21 335 24 22 421 35 30 443 37 32 504 16 14 504 17 15 607 42 36 683 56 47 710 26 24 710 27 25 710 27 25 711 59 50 759 62 53 759 63 54 777 66 56 805 71 61 899 81 68 911 82 69 929 83 70 929 84 71 979 89 75 1334 51 43 1416 57 48 1416 58 49 1584 29 26 1584 29 26 1584 31 27 1584 32 28 1584 32 28 1891 49 41 1922 87 73 1922 88 74 2005 52 44 2005 52 44 2005 54 45 2005 55 46 2518 45 38 2518 46 39 2518 46 39 2518 48 40 2523 73 63 2523 73 63 2523 75 64 2523 76 65 2523 77 66} do_execsql_test 5.1.6.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 2 113 113 2 133 133 1 148 148 1 158 158 1 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 346 346 1 354 354 1 355 355 1 355 355 1 393 393 2 393 393 2 398 398 1 399 399 1 399 399 1 412 412 1 421 421 1 430 430 1 443 443 1 480 480 2 480 480 2 572 572 1 574 574 1 607 607 1 |
︙ | ︙ | |||
3814 3815 3816 3817 3818 3819 3820 | 938 938 2 938 938 2 959 959 1 963 963 1 979 979 1} do_execsql_test 5.1.6.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | | | 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 | 938 938 2 938 938 2 959 959 1 963 963 1 979 979 1} do_execsql_test 5.1.6.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 11 9 {} 12 10 {} 13 11 {} 16 14 {} 17 15 {} 18 16 {} 22 20 {} 24 22 {} 25 23 {} 26 24 {} 31 27 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 {} 49 41 {} 50 42 {} 51 43 {} 54 45 {} 59 50 {} 60 51 {} 61 52 {} 63 54 {} 64 55 {} 64 55 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 75 64 {} 76 65 {} 78 67 {} 78 67 {} 78 67 {} 84 71 {} 85 72 {} 85 72 133 4 3 223 10 8 226 2 2 226 2 2 239 14 12 247 15 13 257 19 17 295 20 18 309 21 19 335 23 21 421 35 30 443 37 32 607 42 36 627 45 38 633 48 40 671 55 46 683 56 47 705 57 48 710 27 25 710 27 25 711 58 49 759 62 53 777 66 56 786 29 26 786 29 26 798 32 28 798 32 28 805 71 61 845 77 66 899 81 68 911 82 69 929 83 70 959 87 73 963 88 74 979 89 75 1258 46 39 1258 46 39 1334 52 44 1334 52 44 1678 73 63 1678 73 63} do_execsql_test 5.1.7.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 113 81 979 113 82 979 133 80 979 148 79 979 158 77 979 158 78 979 160 77 979 208 76 979 223 75 979 224 74 979 234 73 979 238 72 979 239 71 979 247 70 979 250 69 979 252 68 979 256 67 979 257 66 979 295 65 979 309 64 979 330 63 979 335 62 979 336 61 979 346 60 979 354 59 979 355 58 979 355 58 979 393 56 979 393 57 979 398 55 979 399 54 979 399 54 979 412 53 979 421 52 979 430 51 |
︙ | ︙ | |||
3860 3861 3862 3863 3864 3865 3866 | 979 870 11 979 870 11 979 899 9 979 911 8 979 929 7} do_execsql_test 5.1.7.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 | 979 870 11 979 870 11 979 899 9 979 911 8 979 929 7} do_execsql_test 5.1.7.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {3830 89 89 4741 88 88 5640 84 84 5640 85 85 5640 86 86 5640 87 87 6485 81 81 6485 82 82 6485 83 83 7324 80 80 8163 78 78 8163 79 79 8968 73 73 8968 74 74 8968 75 75 8968 76 76 8968 77 77 9745 69 69 9745 70 70 9745 71 71 9745 72 72 10504 65 65 10504 66 66 10504 67 67 10504 68 68 11215 64 64 11920 63 63 12603 62 62 13274 60 60 13274 61 61 13941 59 59 14608 55 55 14608 56 56 14608 57 57 14608 58 58 15241 54 54 15870 53 53 16499 52 52 17126 49 49 17126 50 50 17126 51 51 17733 44 44 17733 45 45 17733 46 46 17733 47 47 17733 48 48 18176 42 42 18176 43 43 18597 40 40 18597 41 41 18996 39 39 19395 37 37 19395 38 38 19788 36 36 20181 35 35 20536 34 34 20891 30 30 20891 31 31 20891 32 32 20891 33 33 21226 28 28 21226 29 29 21535 27 27 21830 26 26 22087 22 22 22087 23 23 22087 24 24 22087 25 25 22334 21 21 22573 17 17 22573 18 18 22573 19 19 22573 20 20 22796 11 11 22796 12 12 22796 13 13 22796 14 14 22796 15 15 22796 16 16 22929 10 10 23042 9 9 23155 1 1 23155 2 2 23155 3 3 23155 4 4 23155 5 5 23155 6 6 23155 7 7 23155 8 8} do_execsql_test 5.1.8.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83} do_execsql_test 5.1.8.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1} do_execsql_test 5.1.9.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33} do_execsql_test 5.1.9.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2050 84 11 2050 84 11 2050 84 11 2050 84 11 2050 84 11 2050 84 11 4997 75 10 4997 75 10 4997 75 10 4997 75 10 4997 75 10 4997 75 10 4997 75 10 4997 75 10 4997 75 10 7337 68 9 7337 68 9 7337 68 9 7337 68 9 7337 68 9 7337 68 9 7337 68 9 10450 59 8 10450 59 8 10450 59 8 10450 59 8 10450 59 8 10450 59 8 10450 59 8 10450 59 8 10450 59 8 11714 51 7 11714 51 7 11714 51 7 11714 51 7 11714 51 7 11714 51 7 11714 51 7 11714 51 7 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 14195 35 5 14195 35 5 14195 35 5 14195 35 5 14195 35 5 15999 28 4 15999 28 4 15999 28 4 15999 28 4 15999 28 4 15999 28 4 15999 28 4 17365 22 3 17365 22 3 17365 22 3 17365 22 3 17365 22 3 17365 22 3 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1} do_execsql_test 5.1.10.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {777 113 5 777 113 5 777 113 5 777 113 5 777 113 5 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 822 158 6 822 158 6 822 158 6 822 158 6 822 158 6 822 158 6 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 938 148 8 938 148 8 938 148 8 938 148 8 938 148 8 938 148 8 938 148 8 938 148 8 959 224 7 959 224 7 959 224 7 959 224 7 959 224 7 959 224 7 959 224 7 979 133 9 979 133 9 979 133 9 979 133 9 979 133 9 979 133 9 979 133 9 979 133 9 979 133 9} do_execsql_test 5.1.10.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1366 1 1 1366 1 1 1366 1 1 1366 1 1 1366 1 1 1366 1 1 1519 1 1 1519 1 1 1519 1 1 1519 1 1 1519 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1} do_execsql_test 5.1.11.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 58 959 102 58 959 102 58 959 102 58 959 102 58 959 102 58 959 102 58 959 102 58 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39 959 158 34 959 158 34 959 158 34 959 158 34 959 158 34 959 158 34 959 158 34 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 53 979 102 53 979 102 53 979 102 53 979 102 53 979 102 53 979 102 53 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 59 979 102 59 979 102 59 979 102 59 979 102 59 979 102 59 979 102 59 979 102 59 979 102 59} do_execsql_test 5.1.11.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 7156 22 3 7156 22 3 7156 22 3 7156 22 3 7156 22 3 7156 22 3 8960 28 4 8960 28 4 8960 28 4 8960 28 4 8960 28 4 8960 28 4 8960 28 4 10479 35 5 10479 35 5 10479 35 5 10479 35 5 10479 35 5 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 12368 68 9 12368 68 9 12368 68 9 12368 68 9 12368 68 9 12368 68 9 12368 68 9 12705 51 7 12705 51 7 12705 51 7 12705 51 7 12705 51 7 12705 51 7 12705 51 7 12705 51 7 13509 59 8 13509 59 8 13509 59 8 13509 59 8 13509 59 8 13509 59 8 13509 59 8 13509 59 8 13509 59 8 13949 75 10 13949 75 10 13949 75 10 13949 75 10 13949 75 10 13949 75 10 13949 75 10 13949 75 10 13949 75 10 14195 84 11 14195 84 11 14195 84 11 14195 84 11 14195 84 11 14195 84 11} do_execsql_test 5.1.12.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 2 113 113 2 133 133 1 148 148 1 160 158 2 160 158 2 160 158 2 208 208 1 224 223 2 224 223 2 239 234 3 239 234 3 239 234 3 252 247 3 257 247 5 257 247 5 257 250 4 257 252 3 295 295 1 309 309 1 336 330 3 336 330 3 336 330 3 346 346 1 355 354 2 355 354 2 355 354 2 399 393 4 399 393 4 399 393 4 399 393 4 399 393 4 412 412 1 421 421 1 430 430 1 443 443 1 480 480 2 480 480 2 574 572 2 574 572 2 607 607 1 618 618 2 618 618 2 634 627 4 634 627 4 634 627 4 634 627 4 634 629 3 652 652 1 667 660 2 671 667 3 671 667 3 671 667 3 671 667 3 683 683 1 711 705 2 716 705 3 716 711 2 730 726 2 730 726 2 762 759 2 768 759 4 768 762 3 768 762 3 777 777 1 792 786 3 794 786 4 794 786 4 794 790 3 805 805 1 822 822 1 845 839 5 845 839 5 845 839 5 845 839 5 845 839 5 870 870 2 870 870 2 870 870 2 899 899 1 911 911 1 934 929 2 938 929 4 938 934 3 938 934 3 963 959 2 963 959 2 979 979 1} do_execsql_test 5.1.12.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 25 23 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 {} 50 42 {} 60 51 {} 61 52 {} 64 55 {} 64 55 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 85 72 {} 85 72 133 4 3 223 10 8 223 11 9 226 2 2 226 2 2 239 12 10 239 13 11 239 14 12 247 15 13 257 18 16 257 19 17 295 20 18 309 21 19 335 22 20 335 23 21 335 24 22 421 35 30 443 37 32 504 16 14 504 17 15 607 42 36 683 56 47 710 26 24 710 27 25 710 27 25 711 59 50 759 62 53 759 63 54 777 66 56 805 71 61 899 81 68 911 82 69 929 83 70 929 84 71 979 89 75 1334 51 43 1416 57 48 1416 58 49 1584 29 26 1584 29 26 1584 31 27 1584 32 28 1584 32 28 1891 49 41 1922 87 73 1922 88 74 2005 52 44 2005 52 44 2005 54 45 2005 55 46 2518 45 38 2518 46 39 2518 46 39 2518 48 40 2523 73 63 2523 73 63 2523 75 64 2523 76 65 2523 77 66} do_execsql_test 5.1.13.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 2 113 113 2 133 133 1 148 148 1 158 158 1 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 346 346 1 354 354 1 355 355 1 355 355 1 393 393 2 393 393 2 398 398 1 399 399 1 399 399 1 412 412 1 421 421 1 430 430 1 443 443 1 480 480 2 480 480 2 572 572 1 574 574 1 607 607 1 618 618 2 618 618 2 627 627 1 629 629 1 629 629 1 633 633 1 634 634 1 652 652 1 660 660 1 667 667 1 667 667 1 670 670 1 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1 730 730 1 759 759 1 762 762 1 768 768 2 768 768 2 777 777 1 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1 839 839 2 839 839 2 840 840 1 844 844 1 845 845 1 870 870 2 870 870 2 870 870 2 899 899 1 911 911 1 929 929 1 934 934 1 938 938 2 938 938 2 959 959 1 963 963 1 979 979 1} do_execsql_test 5.1.13.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 11 9 {} 12 10 {} 13 11 {} 16 14 {} 17 15 {} 18 16 {} 22 20 {} 24 22 {} 25 23 {} 26 24 {} 31 27 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 {} 49 41 {} 50 42 {} 51 43 {} 54 45 {} 59 50 {} 60 51 {} 61 52 {} 63 54 {} 64 55 {} 64 55 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 75 64 {} 76 65 {} 78 67 {} 78 67 {} 78 67 {} 84 71 {} 85 72 {} 85 72 133 4 3 223 10 8 226 2 2 226 2 2 239 14 12 247 15 13 257 19 17 295 20 18 309 21 19 335 23 21 421 35 30 443 37 32 607 42 36 627 45 38 633 48 40 671 55 46 683 56 47 705 57 48 710 27 25 710 27 25 711 58 49 759 62 53 777 66 56 786 29 26 786 29 26 798 32 28 798 32 28 805 71 61 845 77 66 899 81 68 911 82 69 929 83 70 959 87 73 963 88 74 979 89 75 1258 46 39 1258 46 39 1334 52 44 1334 52 44 1678 73 63 1678 73 63} do_execsql_test 5.1.14.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 113 81 979 113 82 979 133 80 979 148 79 979 158 77 979 158 78 979 160 77 979 208 76 979 223 75 979 224 74 979 234 73 979 238 72 979 239 71 979 247 70 979 250 69 979 252 68 979 256 67 979 257 66 979 295 65 979 309 64 979 330 63 979 335 62 979 336 61 979 346 60 979 354 59 979 355 57 979 355 58 979 393 56 979 393 57 979 398 55 979 399 53 979 399 54 979 412 53 979 421 52 979 430 51 979 443 50 979 480 48 979 480 49 979 572 47 979 574 46 979 607 45 979 618 43 979 618 44 979 627 42 979 629 40 979 629 41 979 633 40 979 634 39 979 652 38 979 660 37 979 667 35 979 667 36 979 670 35 979 671 34 979 683 33 979 705 32 979 711 31 979 716 30 979 726 29 979 730 28 979 759 27 979 762 26 979 768 24 979 768 25 979 777 23 979 786 22 979 790 21 979 792 20 979 794 19 979 805 18 979 822 17 979 839 15 979 839 16 979 840 14 979 844 13 979 845 12 979 870 9 979 870 10 979 870 11 979 899 9 979 911 8 979 929 7} do_execsql_test 5.1.14.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {3830 89 89 4741 88 88 5640 84 84 5640 85 85 5640 86 86 5640 87 87 6485 81 81 6485 82 82 6485 83 83 7324 80 80 8163 78 78 8163 79 79 8968 73 73 8968 74 74 8968 75 75 8968 76 76 8968 77 77 9745 69 69 9745 70 70 9745 71 71 9745 72 72 10504 65 65 10504 66 66 10504 67 67 10504 68 68 11215 64 64 11920 63 63 12603 62 62 13274 60 60 13274 61 61 13941 59 59 14608 55 55 14608 56 56 14608 57 57 14608 58 58 15241 54 54 15870 53 53 16499 52 52 |
︙ | ︙ | |||
3887 3888 3889 3890 3891 3892 3893 | do_execsql_test 5.2.1.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) | | | 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 | do_execsql_test 5.2.1.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {963 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 |
︙ | ︙ | |||
3910 3911 3912 3913 3914 3915 3916 | do_execsql_test 5.2.1.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) | | | 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 | do_execsql_test 5.2.1.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {22176 1 1 22192 1 1 22196 1 1 22226 1 1 22244 1 1 22256 1 1 22310 1 1 22316 1 1 22316 1 1 22350 1 1 22378 1 1 22396 1 1 22444 1 1 22450 1 1 22472 1 1 22484 1 1 22488 1 1 22488 1 1 22522 1 1 22526 1 1 22526 1 1 22528 1 1 22548 1 1 22712 1 1 22734 1 1 22756 1 1 22756 1 1 22762 1 1 22762 1 1 22800 1 1 22800 1 1 22820 1 1 22846 1 1 22860 1 1 22898 1 1 22908 1 1 22916 1 1 22932 1 1 23022 1 1 23042 1 1 23042 1 1 23155 1 1 |
︙ | ︙ | |||
3932 3933 3934 3935 3936 3937 3938 | 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1} do_execsql_test 5.2.2.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 | | | | 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 | 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1} do_execsql_test 5.2.2.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {839 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 15 899 113 15 899 113 15 899 113 15 899 113 15 899 113 15 899 113 15 899 234 8 963 113 24 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 48 979 102 48 979 102 48 979 102 48 979 102 48 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 61 979 102 61 979 102 61 |
︙ | ︙ | |||
3956 3957 3958 3959 3960 3961 3962 | 979 113 32 979 113 32 979 113 32 979 113 32 979 113 43} do_execsql_test 5.2.2.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 | 979 113 32 979 113 32 979 113 32 979 113 32 979 113 43} do_execsql_test 5.2.2.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2048 81 11 2108 81 11 2108 81 11 2690 81 11 2834 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 4482 74 10 4616 74 10 4844 74 10 4866 74 10 5287 74 10 5287 74 10 5287 74 10 7421 65 9 7437 65 9 7717 65 9 8045 65 9 8267 65 9 8400 65 9 8400 65 9 8400 65 9 8400 65 9 8735 57 8 9329 57 8 9664 57 8 9664 57 8 9664 57 8 9664 57 8 9664 57 8 9664 57 8 9959 46 7 10331 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7 |
︙ | ︙ | |||
3982 3983 3984 3985 3986 3987 3988 | do_execsql_test 5.2.3.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) | | | 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 | do_execsql_test 5.2.3.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {667 158 0 671 250 6 759 158 5 768 113 4 777 113 4 777 113 4 777 113 4 777 252 4 792 247 12 805 250 6 805 250 6 805 250 6 805 250 6 805 250 6 805 398 6 822 158 5 822 158 5 822 158 5 822 158 5 822 346 5 839 113 8 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 393 12 845 224 6 870 102 10 870 158 0 870 158 0 870 158 0 870 158 0 870 355 0 899 113 8 899 113 8 |
︙ | ︙ | |||
4006 4007 4008 4009 4010 4011 4012 | do_execsql_test 5.2.3.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) | | | | | 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 | do_execsql_test 5.2.3.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {295 1 1 335 1 1 607 1 1 667 1 1 742 1 1 759 1 1 845 1 1 890 1 1 929 1 1 959 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1366 1 1 1366 1 1 1366 1 1 1366 1 1 1383 1 1 1398 1 1 1406 1 1 1421 1 1 1519 1 1 1519 1 1 1535 1 1 1651 1 1 1669 1 1 1682 1 1 1695 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1897 1 1 1919 1 1 2000 1 1 2048 1 1 2050 1 1 2050 1 1 2070 1 1 2086 1 1 2108 1 1 2108 1 1 2134 1 1 2150 1 1 2309 1 1 2309 1 1 2309 1 1 2340 1 1 2340 1 1 2340 1 1 2430 1 1 2690 1 1 2758 1 1 2770 1 1 2776 1 1 2834 1 1 2848 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2980 1 1 3082 1 1 3088 1 1 3088 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3234 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1} do_execsql_test 5.2.4.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {667 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 355 0 911 158 7 934 158 7 934 158 7 934 158 7 934 158 7 934 158 7 934 158 7 934 158 7 934 158 20 934 158 20 934 158 20 934 158 20 934 158 20 934 158 20 934 158 20 934 158 20 934 158 20 934 158 20 934 158 20 934 158 20 934 158 20 934 158 26 934 158 26 934 158 26 934 158 26 934 158 26 934 158 26 934 158 33 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 |
︙ | ︙ | |||
4049 4050 4051 4052 4053 4054 4055 | 979 102 58 979 102 58 979 102 58 979 102 58 979 102 58} do_execsql_test 5.2.4.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 | 979 102 58 979 102 58 979 102 58 979 102 58 979 102 58} do_execsql_test 5.2.4.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {1383 1 1 1421 1 1 1651 1 1 1695 1 1 2050 1 1 2050 1 1 3448 7 2 3732 7 2 4050 7 2 4120 7 2 4136 7 2 4359 7 2 4359 7 2 4359 7 2 7129 15 3 7135 15 3 7207 15 3 7441 15 3 7447 15 3 7447 15 3 7593 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 8447 28 4 8599 28 4 9206 28 4 9206 28 4 9206 28 4 9206 28 4 10051 34 5 10165 34 5 11010 34 5 11010 34 5 11010 34 5 11010 34 5 11010 34 5 11563 74 10 11697 74 10 11752 41 6 |
︙ | ︙ | |||
4073 4074 4075 4076 4077 4078 4079 | 13949 81 11 13949 81 11 13949 81 11} do_execsql_test 5.2.5.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 | | | | 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 | 13949 81 11 13949 81 11 13949 81 11} do_execsql_test 5.2.5.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 113 113 1 113 113 1 158 158 1 160 158 1 160 158 2 223 223 1 224 224 1 238 234 2 239 234 2 239 238 2 252 250 2 256 252 2 257 247 4 257 247 4 257 250 3 335 330 2 336 330 2 336 335 2 355 354 1 355 354 2 355 355 1 399 393 3 399 393 3 399 393 3 399 393 3 |
︙ | ︙ | |||
4096 4097 4098 4099 4100 4101 4102 | 959 959 1 963 963 1} do_execsql_test 5.2.5.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | | | | | | | 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 | 959 959 1 963 963 1} do_execsql_test 5.2.5.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 14 12 {} 15 13 {} 19 17 {} 20 18 {} 21 19 {} 23 21 {} 25 23 {} 34 29 {} 35 30 {} 36 31 {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 {} 43 37 {} 50 42 {} 56 47 {} 60 51 {} 61 52 {} 62 53 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 85 72 {} 85 72 {} 89 75 113 2 2 113 2 2 223 11 9 239 12 10 239 13 11 257 18 16 335 22 20 335 24 22 355 27 25 355 27 25 504 16 14 504 17 15 705 58 49 710 26 24 711 57 48 711 59 50 759 63 54 929 84 71 959 88 74 963 87 73 1185 32 28 1185 32 28 1191 29 26 1191 29 26 1334 51 43 1334 55 46 1338 52 44 1338 52 44 1584 31 27 1678 77 66 1684 73 63 1684 73 63 1885 48 40 1889 46 39 1889 46 39 1891 45 38 1891 49 41 2005 54 45 2523 75 64 2523 76 65} do_execsql_test 5.2.6.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 113 113 1 113 113 1 158 158 0 158 158 1 355 355 0 355 355 1 393 393 1 393 393 1 399 399 0 399 399 1 480 480 1 480 480 1 618 618 1 618 618 1 629 629 0 629 629 1 667 667 0 667 667 1 768 768 1 768 768 1 839 839 1 839 839 1 870 870 1 870 870 1 870 870 2 938 938 1 938 938 1} do_execsql_test 5.2.6.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 11 9 {} 12 10 {} 13 11 {} 14 12 {} 15 13 {} 16 14 {} 17 15 {} 18 16 {} 19 17 {} 20 18 {} 21 19 {} 22 20 {} 23 21 {} 24 22 {} 25 23 {} 26 24 {} 31 27 {} 34 29 {} 35 30 {} 36 31 {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 {} 43 37 {} 45 38 {} 48 40 {} 49 41 {} 50 42 {} 51 43 {} 54 45 {} 55 46 {} 56 47 {} 57 48 {} 58 49 {} 59 50 {} 60 51 {} 61 52 {} 62 53 {} 63 54 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61 {} 72 62 {} 75 64 {} 76 65 {} 77 66 {} 78 67 {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 84 71 {} 85 72 {} 85 72 {} 87 73 {} 88 74 {} 89 75 113 2 2 113 2 2 355 27 25 355 27 25 393 29 26 393 29 26 399 32 28 399 32 28 629 46 39 629 46 39 667 52 44 667 52 44 839 73 63 839 73 63} do_execsql_test 5.2.7.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {963 929 6 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 83 979 113 80 979 113 81 979 113 82 979 133 79 979 148 78 979 158 76 979 158 77 979 160 76 979 208 75 979 223 74 979 224 73 979 234 72 979 238 71 979 239 70 979 247 69 979 250 68 979 252 67 979 256 66 979 257 65 979 295 64 979 309 64 979 330 62 979 335 61 979 336 60 979 346 59 979 354 59 979 355 57 979 355 57 979 393 55 979 393 56 979 398 54 979 399 53 979 399 53 979 412 52 979 421 51 |
︙ | ︙ | |||
4185 4186 4187 4188 4189 4190 4191 | 979 870 9 979 870 10 979 870 10 979 899 8 979 911 7} do_execsql_test 5.2.7.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 | 979 870 9 979 870 10 979 870 10 979 899 8 979 911 7} do_execsql_test 5.2.7.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2851 89 89 3778 88 88 4681 87 87 5556 83 83 5574 82 82 5586 81 81 5640 84 84 5640 85 85 5640 86 86 7324 80 80 8123 77 77 8129 73 73 8129 74 74 8163 78 78 8163 79 79 8940 71 71 8968 75 75 8968 76 76 9727 66 66 9745 69 69 9745 70 70 9745 72 72 10504 65 65 10504 67 67 10504 68 68 11215 64 64 11844 62 62 11920 63 63 13274 60 60 13274 61 61 13897 58 58 13903 57 57 13925 56 56 13937 55 55 13941 59 59 15203 53 53 15241 54 54 15832 52 52 17100 48 48 17104 46 46 17104 47 47 17106 45 45 17126 49 49 17126 50 50 17126 51 51 17569 42 42 17733 44 44 18176 43 43 18597 40 40 18597 41 41 18952 37 37 18996 39 39 19395 38 38 19760 35 35 19788 36 36 20492 32 32 20492 33 33 20498 30 30 20536 34 34 20833 29 29 20871 28 28 20891 31 31 21180 27 27 21752 23 23 21830 26 26 22025 21 21 22087 22 22 22087 24 24 22087 25 25 22278 20 20 22316 19 19 22549 15 15 22557 14 14 22573 17 17 22573 18 18 22706 10 10 22796 11 11 22796 12 12 22796 13 13 22796 16 16 23022 4 4 23042 2 2 23042 3 3 23042 9 9 23155 1 1 23155 5 5 23155 6 6 23155 7 7 23155 8 8} do_execsql_test 5.2.8.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {963 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 113 82} do_execsql_test 5.2.8.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {22176 1 1 22192 1 1 22196 1 1 22226 1 1 22244 1 1 22256 1 1 22310 1 1 22316 1 1 22316 1 1 22350 1 1 22378 1 1 22396 1 1 22444 1 1 22450 1 1 22472 1 1 22484 1 1 22488 1 1 22488 1 1 22522 1 1 22526 1 1 22526 1 1 22528 1 1 22548 1 1 22712 1 1 22734 1 1 22756 1 1 22756 1 1 22762 1 1 22762 1 1 22800 1 1 22800 1 1 22820 1 1 22846 1 1 22860 1 1 22898 1 1 22908 1 1 22916 1 1 22932 1 1 23022 1 1 23042 1 1 23042 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1} do_execsql_test 5.2.9.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {667 158 0 870 113 8 870 158 0 870 158 0 870 158 0 870 158 0 870 355 0 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 15 899 113 15 899 113 15 899 113 15 899 113 15 899 113 15 899 113 15 899 158 8 963 113 24 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 48 979 102 48 979 102 48 979 102 48 979 102 48 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 61 979 102 61 979 102 61 979 102 61 979 102 61 979 102 61 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 113 24 979 113 24 979 113 24 979 113 24 979 113 24 979 113 24 979 113 24 979 113 24 979 113 32 979 113 32 979 113 32 979 113 32 979 113 32 979 113 32 979 113 32 979 113 32 979 113 43} do_execsql_test 5.2.9.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {1383 84 11 1421 84 11 1651 84 11 1695 84 11 2050 84 11 2050 84 11 4098 75 10 4158 75 10 4158 75 10 4740 75 10 4884 75 10 4997 75 10 4997 75 10 4997 75 10 4997 75 10 6532 68 9 6666 68 9 6894 68 9 6916 68 9 7337 68 9 7337 68 9 7337 68 9 9471 59 8 9487 59 8 9767 59 8 10095 59 8 10317 59 8 10450 59 8 10450 59 8 10450 59 8 10450 59 8 10785 51 7 11379 51 7 11714 51 7 11714 51 7 11714 51 7 11714 51 7 11714 51 7 11714 51 7 12009 40 6 12381 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 13418 35 5 13566 35 5 14082 35 5 14195 35 5 14195 35 5 15040 28 4 15154 28 4 15999 28 4 15999 28 4 15999 28 4 15999 28 4 15999 28 4 16606 22 3 16758 22 3 17365 22 3 17365 22 3 17365 22 3 17365 22 3 20135 9 2 20141 9 2 20213 9 2 20447 9 2 20453 9 2 20453 9 2 20599 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 22244 1 1 22528 1 1 22846 1 1 22916 1 1 22932 1 1 23155 1 1 23155 1 1 23155 1 1} do_execsql_test 5.2.10.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {667 158 0 671 250 6 759 158 5 768 113 4 777 113 4 777 113 4 777 113 4 777 252 4 792 247 12 805 250 6 805 250 6 805 250 6 805 250 6 805 250 6 805 398 6 822 158 5 822 158 5 822 158 5 822 158 5 822 346 5 839 113 8 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 393 12 845 224 6 870 102 10 870 158 0 870 158 0 870 158 0 870 158 0 870 355 0 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 234 8 911 223 7 929 148 7 934 223 7 934 223 7 934 223 7 934 223 7 934 223 7 934 223 7 934 239 7 938 102 10 938 102 10 938 102 10 938 102 10 938 102 10 938 102 10 938 102 10 938 102 10 938 102 10 938 148 7 938 148 7 938 148 7 938 148 7 938 148 7 938 148 7 938 160 7 938 208 10 959 224 6 959 224 6 959 224 6 959 224 6 959 224 6 959 238 6 963 133 8 979 133 8 979 133 8 979 133 8 979 133 8 979 133 8 979 133 8 979 133 8 979 330 8} do_execsql_test 5.2.10.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {295 1 1 335 1 1 607 1 1 667 1 1 742 1 1 759 1 1 845 1 1 890 1 1 929 1 1 959 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1366 1 1 1366 1 1 1366 1 1 1366 1 1 1383 1 1 1398 1 1 1406 1 1 1421 1 1 1519 1 1 1519 1 1 1535 1 1 1651 1 1 1669 1 1 1682 1 1 1695 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1897 1 1 1919 1 1 2000 1 1 2048 1 1 2050 1 1 2050 1 1 2070 1 1 2086 1 1 2108 1 1 2108 1 1 2134 1 1 2150 1 1 2309 1 1 2309 1 1 2309 1 1 2340 1 1 2340 1 1 2340 1 1 2430 1 1 2690 1 1 2758 1 1 2770 1 1 2776 1 1 2834 1 1 2848 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2980 1 1 3082 1 1 3088 1 1 3088 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3234 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1} do_execsql_test 5.2.11.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {911 223 7 934 158 26 934 158 26 934 158 26 934 158 26 934 158 26 934 158 33 934 223 7 934 223 7 934 223 7 934 223 7 934 223 7 934 223 7 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 934 223 26 934 239 7 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 959 102 57 959 102 57 959 102 57 959 102 57 959 102 57 959 102 57 959 102 57 959 102 57 959 113 38 959 113 38 959 113 38 959 113 38 959 113 49 959 158 33 959 158 33 959 158 33 959 158 33 959 158 33 959 158 33 959 158 38 963 102 58 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 52 979 102 52 979 102 52 979 102 52 979 102 52 979 102 52 979 102 52 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 58 979 102 58 979 102 58 979 102 58 979 102 58 979 102 58 979 102 58 979 102 58} do_execsql_test 5.2.11.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {1398 1 1 1682 1 1 2000 1 1 2070 1 1 2086 1 1 2309 1 1 2309 1 1 2309 1 1 5079 9 2 5085 9 2 5157 9 2 5391 9 2 5397 9 2 5397 9 2 5543 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 6397 22 3 6549 22 3 7156 22 3 7156 22 3 7156 22 3 7156 22 3 8001 28 4 8115 28 4 8960 28 4 8960 28 4 8960 28 4 8960 28 4 8960 28 4 9702 35 5 9850 35 5 10366 35 5 10479 35 5 10479 35 5 10774 40 6 11146 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11563 68 9 11697 68 9 11776 51 7 11925 68 9 11947 68 9 12368 68 9 12368 68 9 12368 68 9 12370 51 7 12530 59 8 12546 59 8 12705 51 7 12705 51 7 12705 51 7 12705 51 7 12705 51 7 12705 51 7 12826 59 8 13050 75 10 13110 75 10 13110 75 10 13154 59 8 13376 59 8 13509 59 8 13509 59 8 13509 59 8 13509 59 8 13528 84 11 13566 84 11 13692 75 10 13796 84 11 13836 75 10 13840 84 11 13949 75 10 13949 75 10 13949 75 10 13949 75 10 14195 84 11 14195 84 11} do_execsql_test 5.2.12.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 113 113 1 113 113 1 158 158 1 160 158 1 160 158 2 223 223 1 224 224 1 238 234 2 239 234 2 239 238 2 252 250 2 256 252 2 257 247 4 257 247 4 257 250 3 335 330 2 336 330 2 336 335 2 355 354 1 355 354 2 355 355 1 399 393 3 399 393 3 399 393 3 399 393 3 399 393 4 480 480 1 480 480 1 572 572 1 574 574 1 618 618 1 618 618 1 633 629 2 634 627 3 634 627 3 634 627 4 634 629 3 667 667 1 670 667 2 671 667 2 671 667 2 671 667 3 711 711 1 711 711 1 716 705 2 726 726 1 730 730 1 762 762 1 768 759 3 768 762 2 768 762 2 792 790 2 792 790 2 794 786 3 794 786 3 844 839 4 845 839 4 845 839 4 845 839 4 845 839 4 870 870 1 870 870 1 870 870 2 934 934 1 938 929 3 938 934 2 938 934 2 959 959 1 963 963 1} do_execsql_test 5.2.12.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 14 12 {} 15 13 {} 19 17 {} 20 18 {} 21 19 {} 23 21 {} 25 23 {} 34 29 {} 35 30 {} 36 31 {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 {} 43 37 {} 50 42 {} 56 47 {} 60 51 {} 61 52 {} 62 53 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 85 72 {} 85 72 {} 89 75 113 2 2 113 2 2 223 11 9 239 12 10 239 13 11 257 18 16 335 22 20 335 24 22 355 27 25 355 27 25 504 16 14 504 17 15 705 58 49 710 26 24 711 57 48 711 59 50 759 63 54 929 84 71 959 88 74 963 87 73 1185 32 28 1185 32 28 1191 29 26 1191 29 26 1334 51 43 1334 55 46 1338 52 44 1338 52 44 1584 31 27 1678 77 66 1684 73 63 1684 73 63 1885 48 40 1889 46 39 1889 46 39 1891 45 38 1891 49 41 2005 54 45 2523 75 64 2523 76 65} do_execsql_test 5.2.13.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 113 113 1 113 113 1 158 158 0 158 158 1 355 355 0 355 355 1 393 393 1 393 393 1 399 399 0 399 399 1 480 480 1 480 480 1 618 618 1 618 618 1 629 629 0 629 629 1 667 667 0 667 667 1 768 768 1 768 768 1 839 839 1 839 839 1 870 870 1 870 870 1 870 870 2 938 938 1 938 938 1} do_execsql_test 5.2.13.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 11 9 {} 12 10 {} 13 11 {} 14 12 {} 15 13 {} 16 14 {} 17 15 {} 18 16 {} 19 17 {} 20 18 {} 21 19 {} 22 20 {} 23 21 {} 24 22 {} 25 23 {} 26 24 {} 31 27 {} 34 29 {} 35 30 {} 36 31 {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 {} 43 37 {} 45 38 {} 48 40 {} 49 41 {} 50 42 {} 51 43 {} 54 45 {} 55 46 {} 56 47 {} 57 48 {} 58 49 {} 59 50 {} 60 51 {} 61 52 {} 62 53 {} 63 54 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61 {} 72 62 {} 75 64 {} 76 65 {} 77 66 {} 78 67 {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 84 71 {} 85 72 {} 85 72 {} 87 73 {} 88 74 {} 89 75 113 2 2 113 2 2 355 27 25 355 27 25 393 29 26 393 29 26 399 32 28 399 32 28 629 46 39 629 46 39 667 52 44 667 52 44 839 73 63 839 73 63} do_execsql_test 5.2.14.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {963 929 6 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 83 979 113 80 979 113 81 979 113 82 979 133 79 979 148 78 979 158 76 979 158 77 979 160 76 979 208 75 979 223 74 979 224 73 979 234 72 979 238 71 979 239 70 979 247 69 979 250 68 979 252 67 979 256 66 979 257 65 979 295 64 979 309 63 979 330 63 979 335 61 979 336 60 979 346 59 979 354 58 979 355 56 979 355 58 979 393 55 979 393 56 979 398 54 979 399 52 979 399 53 979 412 52 979 421 51 979 430 50 979 443 49 979 480 47 979 480 48 979 572 46 979 574 46 979 607 44 979 618 42 979 618 43 979 627 41 979 629 40 979 629 40 979 633 39 979 634 38 979 652 37 979 660 36 979 667 34 979 667 35 979 670 34 979 671 33 979 683 32 979 705 31 979 711 30 979 716 29 979 726 28 979 730 27 979 759 26 979 762 25 979 768 23 979 768 24 979 777 22 979 786 21 979 790 20 979 792 19 979 794 18 979 805 17 979 822 16 979 839 15 979 839 15 979 840 13 979 844 12 979 845 11 979 870 8 979 870 9 979 870 10 979 899 8 979 911 7} do_execsql_test 5.2.14.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2851 89 89 3778 88 88 4681 87 87 5556 83 83 5574 82 82 5586 81 81 5640 84 84 5640 85 85 5640 86 86 7324 80 80 8123 77 77 8129 73 73 8129 74 74 8163 78 78 8163 79 79 8940 71 71 8968 75 75 8968 76 76 9727 66 66 9745 69 69 9745 70 70 9745 72 72 10504 65 65 10504 67 67 10504 68 68 11215 64 64 11844 62 62 11920 63 63 13274 60 60 13274 61 61 13897 58 58 13903 57 57 13925 56 56 13937 55 55 13941 59 59 15203 53 53 15241 54 54 15832 52 52 |
︙ | ︙ | |||
4212 4213 4214 4215 4216 4217 4218 | do_execsql_test 5.3.1.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) | | | | | | 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 | do_execsql_test 5.3.1.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0} do_execsql_test 5.3.1.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1} do_execsql_test 5.3.2.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 |
︙ | ︙ | |||
4276 4277 4278 4279 4280 4281 4282 | 979 113 33 979 113 33 979 113 33 979 113 33} do_execsql_test 5.3.2.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 | 979 113 33 979 113 33 979 113 33 979 113 33} do_execsql_test 5.3.2.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 2947 74 10 2947 74 10 2947 74 10 2947 74 10 2947 74 10 2947 74 10 2947 74 10 5287 65 9 5287 65 9 5287 65 9 5287 65 9 5287 65 9 5287 65 9 5287 65 9 5287 65 9 5287 65 9 8400 57 8 8400 57 8 8400 57 8 8400 57 8 8400 57 8 8400 57 8 8400 57 8 8400 57 8 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 |
︙ | ︙ | |||
4302 4303 4304 4305 4306 4307 4308 | do_execsql_test 5.3.3.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) | | | 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 | do_execsql_test 5.3.3.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 |
︙ | ︙ | |||
4324 4325 4326 4327 4328 4329 4330 | do_execsql_test 5.3.3.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) | | | | | 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 | do_execsql_test 5.3.3.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1} do_execsql_test 5.3.4.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 959 102 50 959 102 50 959 102 50 |
︙ | ︙ | |||
4366 4367 4368 4369 4370 4371 4372 | 979 102 47 979 102 47 979 102 47 979 102 47} do_execsql_test 5.3.4.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 | 979 102 47 979 102 47 979 102 47 979 102 47} do_execsql_test 5.3.4.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 2050 7 2 2050 7 2 2050 7 2 2050 7 2 2050 7 2 2050 7 2 2050 7 2 2050 7 2 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 7840 28 4 7840 28 4 7840 28 4 7840 28 4 7840 28 4 7840 28 4 9206 34 5 9206 34 5 9206 34 5 9206 34 5 9206 34 5 9206 34 5 9206 34 5 10028 74 10 10028 74 10 10028 74 10 10028 74 10 |
︙ | ︙ | |||
4389 4390 4391 4392 4393 4394 4395 | 12529 46 7 12529 46 7 12529 46 7 12529 46 7 12529 46 7 12529 46 7} do_execsql_test 5.3.5.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 | | | | 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 | 12529 46 7 12529 46 7 12529 46 7 12529 46 7 12529 46 7 12529 46 7} do_execsql_test 5.3.5.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 158 158 1 160 160 1 160 160 1 223 223 1 224 224 1 238 234 2 239 234 2 239 238 2 252 250 2 256 252 2 257 247 4 257 247 4 257 250 3 335 330 2 336 330 2 336 335 2 354 354 1 |
︙ | ︙ | |||
4412 4413 4414 4415 4416 4417 4418 | 963 963 1} do_execsql_test 5.3.5.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | | | | | | | 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 | 963 963 1} do_execsql_test 5.3.5.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 2 2 {} 2 2 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 14 12 {} 15 13 {} 19 17 {} 20 18 {} 21 19 {} 23 21 {} 25 23 {} 27 25 {} 27 25 {} 34 29 {} 35 30 {} 36 31 {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 {} 43 37 {} 50 42 {} 56 47 {} 60 51 {} 61 52 {} 62 53 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 85 72 {} 85 72 {} 89 75 223 11 9 239 12 10 239 13 11 257 18 16 335 22 20 335 24 22 504 16 14 504 17 15 671 52 44 671 52 44 705 58 49 710 26 24 711 57 48 711 59 50 759 63 54 786 32 28 786 32 28 798 29 26 798 29 26 845 73 63 845 73 63 929 84 71 959 88 74 963 87 73 1260 46 39 1260 46 39 1334 51 43 1334 55 46 1584 31 27 1678 77 66 1885 48 40 1891 45 38 1891 49 41 2005 54 45 2523 75 64 2523 76 65} do_execsql_test 5.3.6.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0} do_execsql_test 5.3.6.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 2 2 {} 2 2 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 11 9 {} 12 10 {} 13 11 {} 14 12 {} 15 13 {} 16 14 {} 17 15 {} 18 16 {} 19 17 {} 20 18 {} 21 19 {} 22 20 {} 23 21 {} 24 22 {} 25 23 {} 26 24 {} 27 25 {} 27 25 {} 29 26 {} 29 26 {} 31 27 {} 32 28 {} 32 28 {} 34 29 {} 35 30 {} 36 31 {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 {} 43 37 {} 45 38 {} 46 39 {} 46 39 {} 48 40 {} 49 41 {} 50 42 {} 51 43 {} 52 44 {} 52 44 {} 54 45 {} 55 46 {} 56 47 {} 57 48 {} 58 49 {} 59 50 {} 60 51 {} 61 52 {} 62 53 {} 63 54 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61 {} 72 62 {} 73 63 {} 73 63 {} 75 64 {} 76 65 {} 77 66 {} 78 67 {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 84 71 {} 85 72 {} 85 72 {} 87 73 {} 88 74 {} 89 75} do_execsql_test 5.3.7.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {963 929 6 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 83 979 113 80 979 113 81 979 113 82 979 133 79 979 148 78 979 158 76 979 158 77 979 160 76 979 208 75 979 223 74 979 224 73 979 234 72 979 238 71 979 239 70 979 247 69 979 250 68 979 252 67 979 256 66 979 257 65 979 295 64 979 309 64 979 330 62 979 335 61 979 336 60 979 346 59 979 354 59 979 355 57 979 355 57 979 393 55 979 393 56 979 398 54 979 399 53 979 399 53 979 412 52 979 421 51 |
︙ | ︙ | |||
4500 4501 4502 4503 4504 4505 4506 | 979 870 9 979 870 10 979 870 10 979 899 8 979 911 7} do_execsql_test 5.3.7.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 | 979 870 9 979 870 10 979 870 10 979 899 8 979 911 7} do_execsql_test 5.3.7.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2851 89 89 3778 88 88 4681 87 87 5556 83 83 5574 82 82 5586 81 81 5640 84 84 5640 85 85 5640 86 86 7324 80 80 8123 77 77 8129 73 73 8129 74 74 8163 78 78 8163 79 79 8940 71 71 8968 75 75 8968 76 76 9727 66 66 9745 69 69 9745 70 70 9745 72 72 10504 65 65 10504 67 67 10504 68 68 11215 64 64 11844 62 62 11920 63 63 13274 60 60 13274 61 61 13897 58 58 13903 57 57 13925 56 56 13937 55 55 13941 59 59 15203 53 53 15241 54 54 15832 52 52 17100 48 48 17104 46 46 17104 47 47 17106 45 45 17126 49 49 17126 50 50 17126 51 51 17569 42 42 17733 44 44 18176 43 43 18597 40 40 18597 41 41 18952 37 37 18996 39 39 19395 38 38 19760 35 35 19788 36 36 20492 32 32 20492 33 33 20498 30 30 20536 34 34 20833 29 29 20871 28 28 20891 31 31 21180 27 27 21752 23 23 21830 26 26 22025 21 21 22087 22 22 22087 24 24 22087 25 25 22278 20 20 22316 19 19 22549 15 15 22557 14 14 22573 17 17 22573 18 18 22706 10 10 22796 11 11 22796 12 12 22796 13 13 22796 16 16 23022 4 4 23042 2 2 23042 3 3 23042 9 9 23155 1 1 23155 5 5 23155 6 6 23155 7 7 23155 8 8} do_execsql_test 5.3.8.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0} do_execsql_test 5.3.8.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1} do_execsql_test 5.3.9.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33} do_execsql_test 5.3.9.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 84 11 {} 84 11 {} 84 11 {} 84 11 {} 84 11 {} 84 11 2050 75 10 2050 75 10 2050 75 10 2050 75 10 2050 75 10 2050 75 10 2050 75 10 2050 75 10 2050 75 10 4997 68 9 4997 68 9 4997 68 9 4997 68 9 4997 68 9 4997 68 9 4997 68 9 7337 59 8 7337 59 8 7337 59 8 7337 59 8 7337 59 8 7337 59 8 7337 59 8 7337 59 8 7337 59 8 10450 51 7 10450 51 7 10450 51 7 10450 51 7 10450 51 7 10450 51 7 10450 51 7 10450 51 7 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 12676 35 5 12676 35 5 12676 35 5 12676 35 5 12676 35 5 14195 28 4 14195 28 4 14195 28 4 14195 28 4 14195 28 4 14195 28 4 14195 28 4 15999 22 3 15999 22 3 15999 22 3 15999 22 3 15999 22 3 15999 22 3 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 20846 1 1 20846 1 1 20846 1 1 20846 1 1 20846 1 1 20846 1 1 20846 1 1 20846 1 1} do_execsql_test 5.3.10.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0} do_execsql_test 5.3.10.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1} do_execsql_test 5.3.11.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39 959 158 34 959 158 34 959 158 34 959 158 34 959 158 34 979 102 46 979 102 46 979 102 46 979 102 46 979 102 46 979 102 46 979 102 46 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49} do_execsql_test 5.3.11.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 5790 22 3 5790 22 3 5790 22 3 5790 22 3 5790 22 3 5790 22 3 7156 28 4 7156 28 4 7156 28 4 7156 28 4 7156 28 4 7156 28 4 7156 28 4 8960 35 5 8960 35 5 8960 35 5 8960 35 5 8960 35 5 10028 68 9 10028 68 9 10028 68 9 10028 68 9 10028 68 9 10028 68 9 10028 68 9 10396 59 8 10396 59 8 10396 59 8 10396 59 8 10396 59 8 10396 59 8 10396 59 8 10396 59 8 10396 59 8 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 11002 75 10 11002 75 10 11002 75 10 11002 75 10 11002 75 10 11002 75 10 11002 75 10 11002 75 10 11002 75 10 11441 51 7 11441 51 7 11441 51 7 11441 51 7 11441 51 7 11441 51 7 11441 51 7 11441 51 7 12145 84 11 12145 84 11 12145 84 11 12145 84 11 12145 84 11 12145 84 11} do_execsql_test 5.3.12.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 158 158 1 160 160 1 160 160 1 223 223 1 224 224 1 238 234 2 239 234 2 239 238 2 252 250 2 256 252 2 257 247 4 257 247 4 257 250 3 335 330 2 336 330 2 336 335 2 354 354 1 354 354 1 355 355 1 398 393 3 398 393 3 399 393 3 399 398 2 399 398 2 572 572 1 574 574 1 633 629 2 634 627 3 634 627 3 634 627 3 634 629 3 667 667 1 670 667 2 671 667 2 671 670 2 671 670 2 711 711 1 711 711 1 716 705 2 726 726 1 730 730 1 762 762 1 762 762 1 762 762 1 768 759 3 792 790 2 792 790 2 794 786 3 794 786 3 844 839 4 845 839 4 845 839 4 845 840 3 845 840 3 934 934 1 934 934 1 934 934 1 938 929 3 959 959 1 963 963 1} do_execsql_test 5.3.12.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 2 2 {} 2 2 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 14 12 {} 15 13 {} 19 17 {} 20 18 {} 21 19 {} 23 21 {} 25 23 {} 27 25 {} 27 25 {} 34 29 {} 35 30 {} 36 31 {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 {} 43 37 {} 50 42 {} 56 47 {} 60 51 {} 61 52 {} 62 53 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 85 72 {} 85 72 {} 89 75 223 11 9 239 12 10 239 13 11 257 18 16 335 22 20 335 24 22 504 16 14 504 17 15 671 52 44 671 52 44 705 58 49 710 26 24 711 57 48 711 59 50 759 63 54 786 32 28 786 32 28 798 29 26 798 29 26 845 73 63 845 73 63 929 84 71 959 88 74 963 87 73 1260 46 39 1260 46 39 1334 51 43 1334 55 46 1584 31 27 1678 77 66 1885 48 40 1891 45 38 1891 49 41 2005 54 45 2523 75 64 2523 76 65} do_execsql_test 5.3.13.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0} do_execsql_test 5.3.13.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 2 2 {} 2 2 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 11 9 {} 12 10 {} 13 11 {} 14 12 {} 15 13 {} 16 14 {} 17 15 {} 18 16 {} 19 17 {} 20 18 {} 21 19 {} 22 20 {} 23 21 {} 24 22 {} 25 23 {} 26 24 {} 27 25 {} 27 25 {} 29 26 {} 29 26 {} 31 27 {} 32 28 {} 32 28 {} 34 29 {} 35 30 {} 36 31 {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 {} 43 37 {} 45 38 {} 46 39 {} 46 39 {} 48 40 {} 49 41 {} 50 42 {} 51 43 {} 52 44 {} 52 44 {} 54 45 {} 55 46 {} 56 47 {} 57 48 {} 58 49 {} 59 50 {} 60 51 {} 61 52 {} 62 53 {} 63 54 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61 {} 72 62 {} 73 63 {} 73 63 {} 75 64 {} 76 65 {} 77 66 {} 78 67 {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 84 71 {} 85 72 {} 85 72 {} 87 73 {} 88 74 {} 89 75} do_execsql_test 5.3.14.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {963 929 6 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 83 979 113 80 979 113 81 979 113 82 979 133 79 979 148 78 979 158 76 979 158 77 979 160 76 979 208 75 979 223 74 979 224 73 979 234 72 979 238 71 979 239 70 979 247 69 979 250 68 979 252 67 979 256 66 979 257 65 979 295 64 979 309 63 979 330 63 979 335 61 979 336 60 979 346 59 979 354 58 979 355 56 979 355 58 979 393 55 979 393 56 979 398 54 979 399 52 979 399 53 979 412 52 979 421 51 979 430 50 979 443 49 979 480 47 979 480 48 979 572 46 979 574 46 979 607 44 979 618 42 979 618 43 979 627 41 979 629 40 979 629 40 979 633 39 979 634 38 979 652 37 979 660 36 979 667 34 979 667 35 979 670 34 979 671 33 979 683 32 979 705 31 979 711 30 979 716 29 979 726 28 979 730 27 979 759 26 979 762 25 979 768 23 979 768 24 979 777 22 979 786 21 979 790 20 979 792 19 979 794 18 979 805 17 979 822 16 979 839 15 979 839 15 979 840 13 979 844 12 979 845 11 979 870 8 979 870 9 979 870 10 979 899 8 979 911 7} do_execsql_test 5.3.14.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2851 89 89 3778 88 88 4681 87 87 5556 83 83 5574 82 82 5586 81 81 5640 84 84 5640 85 85 5640 86 86 7324 80 80 8123 77 77 8129 73 73 8129 74 74 8163 78 78 8163 79 79 8940 71 71 8968 75 75 8968 76 76 9727 66 66 9745 69 69 9745 70 70 9745 72 72 10504 65 65 10504 67 67 10504 68 68 11215 64 64 11844 62 62 11920 63 63 13274 60 60 13274 61 61 13897 58 58 13903 57 57 13925 56 56 13937 55 55 13941 59 59 15203 53 53 15241 54 54 15832 52 52 |
︙ | ︙ | |||
4527 4528 4529 4530 4531 4532 4533 | do_execsql_test 5.4.1.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) | | | 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 | do_execsql_test 5.4.1.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1 |
︙ | ︙ | |||
4550 4551 4552 4553 4554 4555 4556 | do_execsql_test 5.4.1.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) | | | | | 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 | do_execsql_test 5.4.1.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 113 1 1 113 1 1 133 1 1 223 1 1 239 1 1 247 1 1 257 1 1 295 1 1 309 1 1 335 1 1 355 1 1 355 1 1 393 1 1 393 1 1 399 1 1 399 1 1 421 1 1 443 1 1 607 1 1 627 1 1 629 1 1 629 1 1 633 1 1 667 1 1 667 1 1 671 1 1 683 1 1 705 1 1 711 1 1 759 1 1 777 1 1 805 1 1 839 1 1 839 1 1 845 1 1 899 1 1 911 1 1 929 1 1 959 1 1 963 1 1 979 1 1} do_execsql_test 5.4.2.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {113 113 1 234 234 1 257 257 1 336 336 1 354 354 1 768 768 1 839 839 1 839 839 1 899 113 10 899 113 10 899 113 10 899 113 10 899 113 10 899 113 10 899 113 10 899 113 17 899 113 17 899 113 17 899 113 17 899 113 17 899 113 17 899 113 17 899 899 1 963 113 17 979 102 34 979 102 45 979 102 45 979 102 45 979 102 45 979 102 45 979 102 50 979 102 50 979 102 50 979 102 50 979 102 50 979 102 50 979 102 50 979 102 57 979 102 57 979 102 57 979 102 57 979 102 57 |
︙ | ︙ | |||
4593 4594 4595 4596 4597 4598 4599 | 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34} do_execsql_test 5.4.2.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 | 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34} do_execsql_test 5.4.2.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 81 11 {} 81 11 {} 81 11 {} 81 11 113 81 11 257 81 11 839 81 11 839 81 11 899 81 11 2947 74 10 2947 74 10 2947 74 10 3368 74 10 3390 74 10 3618 74 10 3752 74 10 5287 65 9 5287 65 9 5287 65 9 5287 65 9 5420 65 9 5642 65 9 5970 65 9 6250 65 9 6266 65 9 8400 57 8 8400 57 8 8400 57 8 8400 57 8 8400 57 8 8400 57 8 8735 57 8 9329 57 8 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 |
︙ | ︙ | |||
4619 4620 4621 4622 4623 4624 4625 | do_execsql_test 5.4.3.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) | | | 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 | do_execsql_test 5.4.3.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1 |
︙ | ︙ | |||
4643 4644 4645 4646 4647 4648 4649 | do_execsql_test 5.4.3.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) | | | | | 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 | do_execsql_test 5.4.3.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 113 1 1 113 1 1 133 1 1 223 1 1 239 1 1 247 1 1 257 1 1 295 1 1 309 1 1 335 1 1 355 1 1 355 1 1 393 1 1 393 1 1 399 1 1 399 1 1 421 1 1 443 1 1 607 1 1 627 1 1 629 1 1 629 1 1 633 1 1 667 1 1 667 1 1 671 1 1 683 1 1 705 1 1 711 1 1 759 1 1 777 1 1 805 1 1 839 1 1 839 1 1 845 1 1 899 1 1 911 1 1 929 1 1 959 1 1 963 1 1 979 1 1} do_execsql_test 5.4.4.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {158 158 0 355 355 0 399 399 0 629 629 0 667 667 0 870 158 1 870 158 1 870 158 1 870 158 1 870 158 1 870 158 1 870 870 0 911 158 1 934 158 1 934 158 9 934 158 9 934 158 9 934 158 9 934 158 9 934 158 9 934 158 9 934 158 9 934 158 9 934 158 9 934 158 9 934 158 9 934 158 9 934 158 22 934 158 22 934 158 22 934 158 22 934 158 22 934 158 22 934 158 28 934 158 28 934 158 28 934 158 28 934 158 28 934 158 28 959 102 40 959 102 51 959 102 51 |
︙ | ︙ | |||
4685 4686 4687 4688 4689 4690 4691 | 979 102 48 979 102 48 979 102 48 979 102 48 979 102 51} do_execsql_test 5.4.4.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 | 979 102 48 979 102 48 979 102 48 979 102 48 979 102 51} do_execsql_test 5.4.4.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 355 1 1 399 1 1 629 1 1 667 1 1 2050 7 2 2050 7 2 2050 7 2 2273 7 2 2289 7 2 2359 7 2 2677 7 2 2961 7 2 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4606 15 3 4752 15 3 4752 15 3 4758 15 3 4992 15 3 5064 15 3 5070 15 3 7840 28 4 7840 28 4 7840 28 4 7840 28 4 8447 28 4 8599 28 4 9206 34 5 9206 34 5 9206 34 5 9206 34 5 9206 34 5 10028 74 10 10028 74 10 10028 74 10 10051 34 5 10165 34 5 |
︙ | ︙ | |||
4709 4710 4711 4712 4713 4714 4715 | 12529 46 7 12529 46 7 12824 46 7 13196 46 7} do_execsql_test 5.4.5.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 | | | | 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 | 12529 46 7 12529 46 7 12824 46 7 13196 46 7} do_execsql_test 5.4.5.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 160 158 1 160 158 2 160 158 2 208 208 1 224 223 2 224 223 2 239 234 3 239 234 3 239 234 3 252 247 3 257 247 5 257 247 5 257 250 4 257 252 3 295 295 1 309 309 1 336 330 3 336 330 3 336 330 3 346 346 1 355 354 1 355 354 2 355 354 2 399 393 3 399 393 3 399 393 3 399 393 4 399 393 4 412 412 1 421 421 1 430 430 1 443 443 1 480 480 1 480 480 1 574 572 2 574 572 2 607 607 1 |
︙ | ︙ | |||
4732 4733 4734 4735 4736 4737 4738 | 938 934 2 938 934 2 963 959 2 963 959 2 979 979 1} do_execsql_test 5.4.5.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | | | 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 | 938 934 2 938 934 2 963 959 2 963 959 2 979 979 1} do_execsql_test 5.4.5.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 25 23 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 {} 50 42 {} 60 51 {} 61 52 {} 64 55 {} 64 55 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 85 72 {} 85 72 113 2 2 113 2 2 133 4 3 223 10 8 223 11 9 239 12 10 239 13 11 239 14 12 247 15 13 257 18 16 257 19 17 295 20 18 309 21 19 335 22 20 335 23 21 335 24 22 355 27 25 355 27 25 421 35 30 443 37 32 504 16 14 504 17 15 607 42 36 683 56 47 710 26 24 711 59 50 759 62 53 759 63 54 777 66 56 805 71 61 899 81 68 911 82 69 929 83 70 929 84 71 979 89 75 1185 32 28 1185 32 28 1191 29 26 1191 29 26 1334 51 43 1338 52 44 1338 52 44 1416 57 48 1416 58 49 1584 31 27 1684 73 63 1684 73 63 1889 46 39 1889 46 39 1891 49 41 1922 87 73 1922 88 74 2005 54 45 2005 55 46 2518 45 38 2518 48 40 2523 75 64 2523 76 65 2523 77 66} do_execsql_test 5.4.6.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1 |
︙ | ︙ | |||
4777 4778 4779 4780 4781 4782 4783 | 938 938 1 938 938 1 959 959 1 963 963 1 979 979 1} do_execsql_test 5.4.6.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | | | | | | 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 | 938 938 1 938 938 1 959 959 1 963 963 1 979 979 1} do_execsql_test 5.4.6.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 11 9 {} 12 10 {} 13 11 {} 16 14 {} 17 15 {} 18 16 {} 22 20 {} 24 22 {} 25 23 {} 26 24 {} 31 27 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 {} 49 41 {} 50 42 {} 51 43 {} 54 45 {} 59 50 {} 60 51 {} 61 52 {} 63 54 {} 64 55 {} 64 55 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 75 64 {} 76 65 {} 78 67 {} 78 67 {} 78 67 {} 84 71 {} 85 72 {} 85 72 113 2 2 113 2 2 133 4 3 223 10 8 239 14 12 247 15 13 257 19 17 295 20 18 309 21 19 335 23 21 355 27 25 355 27 25 393 29 26 393 29 26 399 32 28 399 32 28 421 35 30 443 37 32 607 42 36 627 45 38 629 46 39 629 46 39 633 48 40 667 52 44 667 52 44 671 55 46 683 56 47 705 57 48 711 58 49 759 62 53 777 66 56 805 71 61 839 73 63 839 73 63 845 77 66 899 81 68 911 82 69 929 83 70 959 87 73 963 88 74 979 89 75} do_execsql_test 5.4.7.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 113 81 979 113 82 979 133 80 979 148 79 979 158 77 979 158 78 979 160 77 979 208 76 979 223 75 979 224 74 979 234 73 979 238 72 979 239 71 979 247 70 979 250 69 979 252 68 979 256 67 979 257 66 979 295 65 979 309 64 979 330 63 979 335 62 979 336 61 979 346 60 979 354 59 979 355 58 979 355 58 979 393 56 979 393 57 979 398 55 979 399 54 979 399 54 979 412 53 979 421 52 979 430 51 |
︙ | ︙ | |||
4823 4824 4825 4826 4827 4828 4829 | 979 870 11 979 870 11 979 899 9 979 911 8 979 929 7} do_execsql_test 5.4.7.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 | 979 870 11 979 870 11 979 899 9 979 911 8 979 929 7} do_execsql_test 5.4.7.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {3830 89 89 4741 88 88 5640 84 84 5640 85 85 5640 86 86 5640 87 87 6485 81 81 6485 82 82 6485 83 83 7324 80 80 8163 78 78 8163 79 79 8968 73 73 8968 74 74 8968 75 75 8968 76 76 8968 77 77 9745 69 69 9745 70 70 9745 71 71 9745 72 72 10504 65 65 10504 66 66 10504 67 67 10504 68 68 11215 64 64 11920 63 63 12603 62 62 13274 60 60 13274 61 61 13941 59 59 14608 55 55 14608 56 56 14608 57 57 14608 58 58 15241 54 54 15870 53 53 16499 52 52 17126 49 49 17126 50 50 17126 51 51 17733 44 44 17733 45 45 17733 46 46 17733 47 47 17733 48 48 18176 42 42 18176 43 43 18597 40 40 18597 41 41 18996 39 39 19395 37 37 19395 38 38 19788 36 36 20181 35 35 20536 34 34 20891 30 30 20891 31 31 20891 32 32 20891 33 33 21226 28 28 21226 29 29 21535 27 27 21830 26 26 22087 22 22 22087 23 23 22087 24 24 22087 25 25 22334 21 21 22573 17 17 22573 18 18 22573 19 19 22573 20 20 22796 11 11 22796 12 12 22796 13 13 22796 14 14 22796 15 15 22796 16 16 22929 10 10 23042 9 9 23155 1 1 23155 2 2 23155 3 3 23155 4 4 23155 5 5 23155 6 6 23155 7 7 23155 8 8} do_execsql_test 5.4.8.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1 618 618 1 618 618 1 627 627 1 629 629 0 629 629 1 633 633 1 634 634 1 652 652 1 660 660 1 667 667 0 667 667 1 670 670 1 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1 730 730 1 759 759 1 762 762 1 768 768 1 768 768 1 777 777 1 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1 839 839 1 839 839 1 840 840 1 844 844 1 845 845 1 870 870 0 870 870 1 870 870 1 899 899 1 911 911 1 929 929 1 934 934 1 938 938 1 938 938 1 959 959 1 963 963 1 979 979 1} do_execsql_test 5.4.8.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 113 1 1 113 1 1 133 1 1 223 1 1 239 1 1 247 1 1 257 1 1 295 1 1 309 1 1 335 1 1 355 1 1 355 1 1 393 1 1 393 1 1 399 1 1 399 1 1 421 1 1 443 1 1 607 1 1 627 1 1 629 1 1 629 1 1 633 1 1 667 1 1 667 1 1 671 1 1 683 1 1 705 1 1 711 1 1 759 1 1 777 1 1 805 1 1 839 1 1 839 1 1 845 1 1 899 1 1 911 1 1 929 1 1 959 1 1 963 1 1 979 1 1} do_execsql_test 5.4.9.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {158 158 0 355 355 0 399 399 0 629 629 0 667 667 0 870 113 1 870 158 1 870 158 1 870 158 1 870 158 1 870 158 1 870 158 1 870 158 1 870 870 0 899 113 10 899 113 10 899 113 10 899 113 10 899 113 10 899 113 10 899 113 10 899 113 17 899 113 17 899 113 17 899 113 17 899 113 17 899 113 17 899 113 17 899 158 1 963 113 17 979 102 34 979 102 45 979 102 45 979 102 45 979 102 45 979 102 45 979 102 50 979 102 50 979 102 50 979 102 50 979 102 50 979 102 50 979 102 50 979 102 57 979 102 57 979 102 57 979 102 57 979 102 57 979 102 57 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 979 102 76 979 102 76 979 102 76 979 102 76 979 102 76 979 102 76 979 102 76 979 102 76 979 113 17 979 113 26 979 113 26 979 113 26 979 113 26 979 113 26 979 113 26 979 113 26 979 113 26 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34} do_execsql_test 5.4.9.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 84 11 {} 84 11 355 84 11 399 84 11 629 84 11 667 84 11 2050 75 10 2050 75 10 2050 75 10 2050 75 10 2163 75 10 2307 75 10 2889 75 10 2889 75 10 2949 75 10 4997 68 9 4997 68 9 4997 68 9 5418 68 9 5440 68 9 5668 68 9 5802 68 9 7337 59 8 7337 59 8 7337 59 8 7337 59 8 7470 59 8 7692 59 8 8020 59 8 8300 59 8 8316 59 8 10450 51 7 10450 51 7 10450 51 7 10450 51 7 10450 51 7 10450 51 7 10785 51 7 11379 51 7 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 12009 40 6 12381 40 6 12676 35 5 12676 35 5 12789 35 5 13305 35 5 13453 35 5 14195 28 4 14195 28 4 14195 28 4 14195 28 4 14195 28 4 15040 28 4 15154 28 4 15999 22 3 15999 22 3 15999 22 3 15999 22 3 16606 22 3 16758 22 3 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17612 9 2 17758 9 2 17758 9 2 17764 9 2 17998 9 2 18070 9 2 18076 9 2 20846 1 1 20846 1 1 20846 1 1 21069 1 1 21085 1 1 21155 1 1 21473 1 1 21757 1 1} do_execsql_test 5.4.10.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1 618 618 1 618 618 1 627 627 1 629 629 0 629 629 1 633 633 1 634 634 1 652 652 1 660 660 1 667 667 0 667 667 1 670 670 1 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1 730 730 1 759 759 1 762 762 1 768 768 1 768 768 1 777 777 1 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1 839 839 1 839 839 1 840 840 1 844 844 1 845 845 1 870 870 0 870 870 1 870 870 1 899 899 1 911 911 1 929 929 1 934 934 1 938 938 1 938 938 1 959 959 1 963 963 1 979 979 1} do_execsql_test 5.4.10.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 113 1 1 113 1 1 133 1 1 223 1 1 239 1 1 247 1 1 257 1 1 295 1 1 309 1 1 335 1 1 355 1 1 355 1 1 393 1 1 393 1 1 399 1 1 399 1 1 421 1 1 443 1 1 607 1 1 627 1 1 629 1 1 629 1 1 633 1 1 667 1 1 667 1 1 671 1 1 683 1 1 705 1 1 711 1 1 759 1 1 777 1 1 805 1 1 839 1 1 839 1 1 845 1 1 899 1 1 911 1 1 929 1 1 959 1 1 963 1 1 979 1 1} do_execsql_test 5.4.11.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {223 223 1 239 239 1 309 309 1 572 572 1 627 627 1 870 870 1 911 911 1 934 158 22 934 158 28 934 158 28 934 158 28 934 158 28 934 158 28 934 158 28 934 223 9 934 223 9 934 223 9 934 223 9 934 223 9 934 223 9 934 223 9 934 223 9 934 223 9 934 223 9 934 223 9 934 223 9 934 223 9 934 223 22 934 223 22 934 223 22 934 223 22 934 223 22 934 934 1 959 102 40 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 113 35 959 113 40 959 113 40 959 113 40 959 113 40 959 113 40 959 113 40 959 113 40 959 113 40 959 113 40 959 113 40 959 158 28 959 158 35 959 158 35 959 158 35 959 158 35 963 102 51 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 979 102 48 979 102 48 979 102 48 979 102 48 979 102 48 979 102 48 979 102 48 979 102 48 979 102 48 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 51} do_execsql_test 5.4.11.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 223 1 1 239 1 1 309 1 1 627 1 1 911 1 1 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2556 9 2 2702 9 2 2702 9 2 2708 9 2 2942 9 2 3014 9 2 3020 9 2 5790 22 3 5790 22 3 5790 22 3 5790 22 3 6397 22 3 6549 22 3 7156 28 4 7156 28 4 7156 28 4 7156 28 4 7156 28 4 8001 28 4 8115 28 4 8960 35 5 8960 35 5 9073 35 5 9589 35 5 9737 35 5 10028 68 9 10028 68 9 10028 68 9 10396 59 8 10396 59 8 10396 59 8 10396 59 8 10449 68 9 10471 68 9 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10529 59 8 10699 68 9 10751 59 8 10774 40 6 10833 68 9 11002 75 10 11002 75 10 11002 75 10 11002 75 10 11079 59 8 11115 75 10 11146 40 6 11259 75 10 11359 59 8 11375 59 8 11441 51 7 11441 51 7 11441 51 7 11441 51 7 11441 51 7 11441 51 7 11776 51 7 11841 75 10 11841 75 10 11901 75 10 12145 84 11 12145 84 11 12370 51 7 12500 84 11 12544 84 11 12774 84 11 12812 84 11} do_execsql_test 5.4.12.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 160 158 1 160 158 2 160 158 2 208 208 1 224 223 2 224 223 2 239 234 3 239 234 3 239 234 3 252 247 3 257 247 5 257 247 5 257 250 4 257 252 3 295 295 1 309 309 1 336 330 3 336 330 3 336 330 3 346 346 1 355 354 1 355 354 2 355 354 2 399 393 3 399 393 3 399 393 3 399 393 4 399 393 4 412 412 1 421 421 1 430 430 1 443 443 1 480 480 1 480 480 1 574 572 2 574 572 2 607 607 1 618 618 1 618 618 1 634 627 3 634 627 4 634 627 4 634 627 4 634 629 3 652 652 1 667 660 2 671 667 2 671 667 3 671 667 3 671 667 3 683 683 1 711 705 2 716 705 3 716 711 2 730 726 2 730 726 2 762 759 2 768 759 4 768 762 2 768 762 2 777 777 1 792 786 3 794 786 4 794 786 4 794 790 3 805 805 1 822 822 1 845 839 4 845 839 4 845 839 5 845 839 5 845 839 5 870 870 0 870 870 1 870 870 1 899 899 1 911 911 1 934 929 2 938 929 4 938 934 2 938 934 2 963 959 2 963 959 2 979 979 1} do_execsql_test 5.4.12.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 25 23 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 {} 50 42 {} 60 51 {} 61 52 {} 64 55 {} 64 55 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 85 72 {} 85 72 113 2 2 113 2 2 133 4 3 223 10 8 223 11 9 239 12 10 239 13 11 239 14 12 247 15 13 257 18 16 257 19 17 295 20 18 309 21 19 335 22 20 335 23 21 335 24 22 355 27 25 355 27 25 421 35 30 443 37 32 504 16 14 504 17 15 607 42 36 683 56 47 710 26 24 711 59 50 759 62 53 759 63 54 777 66 56 805 71 61 899 81 68 911 82 69 929 83 70 929 84 71 979 89 75 1185 32 28 1185 32 28 1191 29 26 1191 29 26 1334 51 43 1338 52 44 1338 52 44 1416 57 48 1416 58 49 1584 31 27 1684 73 63 1684 73 63 1889 46 39 1889 46 39 1891 49 41 1922 87 73 1922 88 74 2005 54 45 2005 55 46 2518 45 38 2518 48 40 2523 75 64 2523 76 65 2523 77 66} do_execsql_test 5.4.13.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1 618 618 1 618 618 1 627 627 1 629 629 0 629 629 1 633 633 1 634 634 1 652 652 1 660 660 1 667 667 0 667 667 1 670 670 1 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1 730 730 1 759 759 1 762 762 1 768 768 1 768 768 1 777 777 1 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1 839 839 1 839 839 1 840 840 1 844 844 1 845 845 1 870 870 0 870 870 1 870 870 1 899 899 1 911 911 1 929 929 1 934 934 1 938 938 1 938 938 1 959 959 1 963 963 1 979 979 1} do_execsql_test 5.4.13.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 11 9 {} 12 10 {} 13 11 {} 16 14 {} 17 15 {} 18 16 {} 22 20 {} 24 22 {} 25 23 {} 26 24 {} 31 27 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 {} 49 41 {} 50 42 {} 51 43 {} 54 45 {} 59 50 {} 60 51 {} 61 52 {} 63 54 {} 64 55 {} 64 55 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 75 64 {} 76 65 {} 78 67 {} 78 67 {} 78 67 {} 84 71 {} 85 72 {} 85 72 113 2 2 113 2 2 133 4 3 223 10 8 239 14 12 247 15 13 257 19 17 295 20 18 309 21 19 335 23 21 355 27 25 355 27 25 393 29 26 393 29 26 399 32 28 399 32 28 421 35 30 443 37 32 607 42 36 627 45 38 629 46 39 629 46 39 633 48 40 667 52 44 667 52 44 671 55 46 683 56 47 705 57 48 711 58 49 759 62 53 777 66 56 805 71 61 839 73 63 839 73 63 845 77 66 899 81 68 911 82 69 929 83 70 959 87 73 963 88 74 979 89 75} do_execsql_test 5.4.14.1 { SELECT max(c) OVER win, min(c) OVER win, count(a) OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 113 81 979 113 82 979 133 80 979 148 79 979 158 77 979 158 78 979 160 77 979 208 76 979 223 75 979 224 74 979 234 73 979 238 72 979 239 71 979 247 70 979 250 69 979 252 68 979 256 67 979 257 66 979 295 65 979 309 64 979 330 63 979 335 62 979 336 61 979 346 60 979 354 59 979 355 57 979 355 58 979 393 56 979 393 57 979 398 55 979 399 53 979 399 54 979 412 53 979 421 52 979 430 51 979 443 50 979 480 48 979 480 49 979 572 47 979 574 46 979 607 45 979 618 43 979 618 44 979 627 42 979 629 40 979 629 41 979 633 40 979 634 39 979 652 38 979 660 37 979 667 35 979 667 36 979 670 35 979 671 34 979 683 33 979 705 32 979 711 31 979 716 30 979 726 29 979 730 28 979 759 27 979 762 26 979 768 24 979 768 25 979 777 23 979 786 22 979 790 21 979 792 20 979 794 19 979 805 18 979 822 17 979 839 15 979 839 16 979 840 14 979 844 13 979 845 12 979 870 9 979 870 10 979 870 11 979 899 9 979 911 8 979 929 7} do_execsql_test 5.4.14.2 { SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, rank() OVER win, dense_rank() OVER win FROM t3 WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES ) ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {3830 89 89 4741 88 88 5640 84 84 5640 85 85 5640 86 86 5640 87 87 6485 81 81 6485 82 82 6485 83 83 7324 80 80 8163 78 78 8163 79 79 8968 73 73 8968 74 74 8968 75 75 8968 76 76 8968 77 77 9745 69 69 9745 70 70 9745 71 71 9745 72 72 10504 65 65 10504 66 66 10504 67 67 10504 68 68 11215 64 64 11920 63 63 12603 62 62 13274 60 60 13274 61 61 13941 59 59 14608 55 55 14608 56 56 14608 57 57 14608 58 58 15241 54 54 15870 53 53 16499 52 52 |
︙ | ︙ | |||
4856 4857 4858 4859 4860 4861 4862 | INSERT INTO t2 VALUES('A', NULL); INSERT INTO t2 VALUES('B', NULL); INSERT INTO t2 VALUES('C', 1); } {} do_execsql_test 6.1 { SELECT group_concat(a, '.') OVER ( | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 | INSERT INTO t2 VALUES('A', NULL); INSERT INTO t2 VALUES('B', NULL); INSERT INTO t2 VALUES('C', 1); } {} do_execsql_test 6.1 { SELECT group_concat(a, '.') OVER ( ORDER BY b NULLS FIRST RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING ) FROM t2 } {A.B A.B {}} do_execsql_test 6.2 { SELECT group_concat(a, '.') OVER ( ORDER BY b DESC NULLS LAST RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING ) FROM t2 } {{} A.B A.B} #========================================================================== do_execsql_test 7.0 { DROP TABLE IF EXISTS t2; CREATE TABLE t2(a INTEGER, b INTEGER); INSERT INTO t2 VALUES(1, 65); INSERT INTO t2 VALUES(2, NULL); INSERT INTO t2 VALUES(3, NULL); INSERT INTO t2 VALUES(4, NULL); INSERT INTO t2 VALUES(5, 66); INSERT INTO t2 VALUES(6, 67); } {} do_execsql_test 7.1.1 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING ); } {9 9 9 9 9 9} do_execsql_test 7.1.2 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING ); } {{} {} {} 9 9 9} do_execsql_test 7.1.3 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING ); } {{} {} {} 9 9 9} do_execsql_test 7.1.4 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING ); } {9 9 9 {} {} {}} do_execsql_test 7.1.5 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING ); } {9 9 9 {} {} {}} do_execsql_test 7.1.6 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING ); } {{} {} 1 9 9 9} do_execsql_test 7.1.7 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING ); } {{} {} {} 9 9 9} do_execsql_test 7.1.8 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING ); } {9 9 9 {} {} {}} do_execsql_test 7.1.9 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING ); } {9 9 9 {} {} {}} do_execsql_test 7.2.1 { SELECT min (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING ); } {2 2 2 2 2 2} do_execsql_test 7.2.2 { SELECT min (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING ); } {{} {} {} 2 2 2} do_execsql_test 7.2.3 { SELECT min (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING ); } {{} {} {} 2 2 2} do_execsql_test 7.2.4 { SELECT min (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING ); } {2 2 2 {} {} {}} do_execsql_test 7.2.5 { SELECT min (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING ); } {2 2 2 {} {} {}} do_execsql_test 7.2.6 { SELECT min (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING ); } {{} {} 1 2 2 2} do_execsql_test 7.2.7 { SELECT min (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING ); } {{} {} {} 2 2 2} do_execsql_test 7.2.8 { SELECT min (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING ); } {2 2 2 {} {} {}} do_execsql_test 7.2.9 { SELECT min (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING ); } {2 2 2 {} {} {}} do_execsql_test 7.3.1 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING ); } {9 9 9 9 9 9} do_execsql_test 7.3.2 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING ); } {{} {} {} 9 9 9} do_execsql_test 7.3.3 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING ); } {{} {} {} 9 9 9} do_execsql_test 7.3.4 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING ); } {9 9 9 {} {} {}} do_execsql_test 7.3.5 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING ); } {9 9 9 {} {} {}} do_execsql_test 7.3.6 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING ); } {{} {} 1 9 9 9} do_execsql_test 7.3.7 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING ); } {{} {} {} 9 9 9} do_execsql_test 7.3.8 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING ); } {9 9 9 {} {} {}} do_execsql_test 7.3.9 { SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING ); } {9 9 9 {} {} {}} do_execsql_test 7.4.1 { SELECT max (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING ); } {4 4 4 4 4 4} do_execsql_test 7.4.2 { SELECT max (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING ); } {{} {} {} 4 4 4} do_execsql_test 7.4.3 { SELECT max (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING ); } {{} {} {} 4 4 4} do_execsql_test 7.4.4 { SELECT max (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING ); } {4 4 4 {} {} {}} do_execsql_test 7.4.5 { SELECT max (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING ); } {4 4 4 {} {} {}} do_execsql_test 7.4.6 { SELECT max (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING ); } {{} {} 1 4 4 4} do_execsql_test 7.4.7 { SELECT max (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING ); } {{} {} {} 4 4 4} do_execsql_test 7.4.8 { SELECT max (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING ); } {4 4 4 {} {} {}} do_execsql_test 7.4.9 { SELECT max (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING ); } {4 4 4 {} {} {}} finish_test |
Changes to test/window9.test.
︙ | ︙ | |||
94 95 96 97 98 99 100 | do_execsql_test 2.2.1 { SELECT b=='2' FROM t1 } {1 0} do_execsql_test 2.2.2 { SELECT b=='2', rank() OVER (ORDER BY a) FROM t1 } {1 1 0 2} | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | do_execsql_test 2.2.1 { SELECT b=='2' FROM t1 } {1 0} do_execsql_test 2.2.2 { SELECT b=='2', rank() OVER (ORDER BY a) FROM t1 } {1 1 0 2} #------------------------------------------------------------------------- reset_db do_execsql_test 3.0 { CREATE TABLE t1(a); CREATE TABLE t2(a,b,c); } do_execsql_test 3.1 { SELECT EXISTS(SELECT 1 FROM t1 ORDER BY sum(a) OVER ()) FROM t1; } do_execsql_test 3.2 { SELECT sum(a) OVER () FROM t2 ORDER BY EXISTS(SELECT 1 FROM t2 ORDER BY sum(a) OVER ()); } do_catchsql_test 3.3 { SELECT a, sum(a) OVER (ORDER BY a DESC) FROM t2 ORDER BY EXISTS( SELECT 1 FROM t2 ORDER BY sum(a) OVER (ORDER BY a) ) OVER (ORDER BY a); } {1 {near "OVER": syntax error}} do_catchsql_test 3.4 { SELECT y, y+1, y+2 FROM ( SELECT c IN ( SELECT min(a) OVER (), (abs(row_number() OVER())+22)/19, max(a) OVER () FROM t1 ) AS y FROM t2 ); } {1 {sub-select returns 3 columns - expected 1}} #------------------------------------------------------------------------- reset_db do_execsql_test 4.0 { CREATE TABLE t1(a, b TEXT); INSERT INTO t1 VALUES('A', 1), ('A', 2), ('2', 1), ('2', 2); } do_execsql_test 4.1.1 { SELECT b, b=count(*), '1,2' FROM t1 GROUP BY b; } {1 0 1,2 2 1 1,2} do_execsql_test 4.1.2 { SELECT b, b=count(*), group_concat(b) OVER () FROM t1 GROUP BY b; } {1 0 1,2 2 1 1,2} #-------------------------------------------------------------------------- reset_db do_execsql_test 5.0 { CREATE TABLE t1(a, b, c, d, e); CREATE INDEX i1 ON t1(a, b, c, d, e); } foreach {tn sql} { 1 { SELECT sum(e) OVER (), sum(e) OVER (ORDER BY a), sum(e) OVER (PARTITION BY a ORDER BY b), sum(e) OVER (PARTITION BY a, b ORDER BY c), sum(e) OVER (PARTITION BY a, b, c ORDER BY d) FROM t1; } 2 { SELECT sum(e) OVER (PARTITION BY a ORDER BY b) FROM t1 ORDER BY a; } } { do_test 5.1.$tn { execsql "EXPLAIN QUERY PLAN $sql" } {~/ORDER/} } #------------------------------------------------------------------------- reset_db do_execsql_test 6.0 { CREATE TABLE t0(c0); INSERT INTO t0(c0) VALUES (0); } do_execsql_test 6.1 { SELECT * FROM t0 WHERE EXISTS ( SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0 ) >=1 AND EXISTS ( SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0 ) <=1; } {0} do_execsql_test 6.2 { SELECT * FROM t0 WHERE EXISTS ( SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0 ) BETWEEN 1 AND 1; } {0} finish_test |
Added test/windowA.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | # 2019-08-30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # Test cases for RANGE BETWEEN and especially with NULLS LAST # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix windowA ifcapable !windowfunc { finish_test return } do_execsql_test 1.0 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b CHAR(1), d FLOAT); INSERT INTO t1 VALUES (1, 'A', 5.4), (2, 'B', 5.55), (3, 'C', 8.0), (4, 'D', 10.25), (5, 'E', 10.26), (6, 'N', NULL), (7, 'N', NULL); } {} do_execsql_test 1.1 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS LAST RANGE BETWEEN 2.50 PRECEDING AND 2.25 FOLLOWING) ORDER BY +d DESC NULLS LAST, +a; } [list \ 5 E 10.26 ED \ 4 D 10.25 EDC \ 3 C 8.0 EDC \ 2 B 5.55 CBA \ 1 A 5.4 BA \ 6 N NULL NN \ 7 N NULL NN \ ] do_execsql_test 1.2 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS FIRST RANGE BETWEEN 2.50 PRECEDING AND 2.25 FOLLOWING) ORDER BY +d DESC NULLS FIRST, +a; } [list \ 6 N NULL NN \ 7 N NULL NN \ 5 E 10.26 ED \ 4 D 10.25 EDC \ 3 C 8.0 EDC \ 2 B 5.55 CBA \ 1 A 5.4 BA \ ] do_execsql_test 1.3 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS LAST RANGE BETWEEN 2.50 PRECEDING AND UNBOUNDED FOLLOWING) ORDER BY +d DESC NULLS LAST, +a; } [list \ 5 E 10.26 EDCBANN \ 4 D 10.25 EDCBANN \ 3 C 8.0 EDCBANN \ 2 B 5.55 CBANN \ 1 A 5.4 BANN \ 6 N NULL NN \ 7 N NULL NN \ ] do_execsql_test 1.4 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS FIRST RANGE BETWEEN 2.50 PRECEDING AND UNBOUNDED FOLLOWING) ORDER BY +d DESC NULLS FIRST, +a; } [list \ 6 N NULL NNEDCBA \ 7 N NULL NNEDCBA \ 5 E 10.26 EDCBA \ 4 D 10.25 EDCBA \ 3 C 8.0 EDCBA \ 2 B 5.55 CBA \ 1 A 5.4 BA \ ] do_execsql_test 1.5 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS LAST RANGE BETWEEN 2.50 PRECEDING AND CURRENT ROW) ORDER BY +d DESC NULLS LAST, +a; } [list \ 5 E 10.26 E \ 4 D 10.25 ED \ 3 C 8.0 EDC \ 2 B 5.55 CB \ 1 A 5.4 BA \ 6 N NULL NN \ 7 N NULL NN \ ] do_execsql_test 1.6 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS FIRST RANGE BETWEEN 2.50 PRECEDING AND CURRENT ROW) ORDER BY +d DESC NULLS FIRST, +a; } [list \ 6 N NULL NN \ 7 N NULL NN \ 5 E 10.26 E \ 4 D 10.25 ED \ 3 C 8.0 EDC \ 2 B 5.55 CB \ 1 A 5.4 BA \ ] do_execsql_test 2.1 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 2.25 FOLLOWING) ORDER BY +d DESC NULLS LAST, +a; } [list \ 5 E 10.26 ED \ 4 D 10.25 EDC \ 3 C 8.0 EDC \ 2 B 5.55 EDCBA \ 1 A 5.4 EDCBA \ 6 N NULL EDCBANN \ 7 N NULL EDCBANN \ ] do_execsql_test 2.2 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 2.25 FOLLOWING) ORDER BY +d DESC NULLS FIRST, +a; } [list \ 6 N NULL NN \ 7 N NULL NN \ 5 E 10.26 NNED \ 4 D 10.25 NNEDC \ 3 C 8.0 NNEDC \ 2 B 5.55 NNEDCBA \ 1 A 5.4 NNEDCBA \ ] do_execsql_test 2.3 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) ORDER BY +d DESC NULLS LAST, +a; } [list \ 5 E 10.26 EDCBANN \ 4 D 10.25 EDCBANN \ 3 C 8.0 EDCBANN \ 2 B 5.55 EDCBANN \ 1 A 5.4 EDCBANN \ 6 N NULL EDCBANN \ 7 N NULL EDCBANN \ ] do_execsql_test 2.4 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) ORDER BY +d DESC NULLS FIRST, +a; } [list \ 6 N NULL NNEDCBA \ 7 N NULL NNEDCBA \ 5 E 10.26 NNEDCBA \ 4 D 10.25 NNEDCBA \ 3 C 8.0 NNEDCBA \ 2 B 5.55 NNEDCBA \ 1 A 5.4 NNEDCBA \ ] do_execsql_test 2.5 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) ORDER BY +d DESC NULLS LAST, +a; } [list \ 5 E 10.26 E \ 4 D 10.25 ED \ 3 C 8.0 EDC \ 2 B 5.55 EDCB \ 1 A 5.4 EDCBA \ 6 N NULL EDCBANN \ 7 N NULL EDCBANN \ ] do_execsql_test 2.6 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) ORDER BY +d DESC NULLS FIRST, +a; } [list \ 6 N NULL NN \ 7 N NULL NN \ 5 E 10.26 NNE \ 4 D 10.25 NNED \ 3 C 8.0 NNEDC \ 2 B 5.55 NNEDCB \ 1 A 5.4 NNEDCBA \ ] do_execsql_test 3.1 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS LAST RANGE BETWEEN CURRENT ROW AND 2.25 FOLLOWING) ORDER BY +d DESC NULLS LAST, +a; } [list \ 5 E 10.26 ED \ 4 D 10.25 DC \ 3 C 8.0 C \ 2 B 5.55 BA \ 1 A 5.4 A \ 6 N NULL NN \ 7 N NULL NN \ ] do_execsql_test 3.2 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS FIRST RANGE BETWEEN CURRENT ROW AND 2.25 FOLLOWING) ORDER BY +d DESC NULLS FIRST, +a; } [list \ 6 N NULL NN \ 7 N NULL NN \ 5 E 10.26 ED \ 4 D 10.25 DC \ 3 C 8.0 C \ 2 B 5.55 BA \ 1 A 5.4 A \ ] do_execsql_test 3.3 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS LAST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) ORDER BY +d DESC NULLS LAST, +a; } [list \ 5 E 10.26 EDCBANN \ 4 D 10.25 DCBANN \ 3 C 8.0 CBANN \ 2 B 5.55 BANN \ 1 A 5.4 ANN \ 6 N NULL NN \ 7 N NULL NN \ ] do_execsql_test 3.4 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) ORDER BY +d DESC NULLS FIRST, +a; } [list \ 6 N NULL NNEDCBA \ 7 N NULL NNEDCBA \ 5 E 10.26 EDCBA \ 4 D 10.25 DCBA \ 3 C 8.0 CBA \ 2 B 5.55 BA \ 1 A 5.4 A \ ] do_execsql_test 4.0 { SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY d DESC NULLS FIRST RANGE BETWEEN 2.50 PRECEDING AND 0.5 PRECEDING) ORDER BY +d DESC NULLS FIRST, +a; } [list \ 6 N NULL NN \ 7 N NULL NN \ 5 E 10.26 {} \ 4 D 10.25 {} \ 3 C 8.0 ED \ 2 B 5.55 C \ 1 A 5.4 {} \ ] finish_test |
Added test/windowB.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | # 2019-08-30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # Test cases for RANGE BETWEEN and especially with NULLS LAST # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix windowB ifcapable !windowfunc { finish_test return } do_execsql_test 1.0 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(NULL, 1); INSERT INTO t1 VALUES(NULL, 2); INSERT INTO t1 VALUES(NULL, 3); } {} foreach {tn win} { 1 { ORDER BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING } 2 { ORDER BY a NULLS LAST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING } 3 { ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING } 4 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING } 5 { ORDER BY a NULLS LAST RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING } 6 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING } 7 { ORDER BY a NULLS LAST RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING } 8 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING } } { do_execsql_test 1.$tn " SELECT sum(b) OVER win FROM t1 WINDOW win AS ( $win ) " {6 6 6} } do_execsql_test 1.2 { SELECT sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING ) } {6 6 6} #------------------------------------------------------------------------- reset_db do_execsql_test 2.0 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, NULL); INSERT INTO t1 VALUES(2, 45); INSERT INTO t1 VALUES(3, 66.2); INSERT INTO t1 VALUES(4, 'hello world'); INSERT INTO t1 VALUES(5, 'hello world'); INSERT INTO t1 VALUES(6, X'1234'); INSERT INTO t1 VALUES(7, X'1234'); INSERT INTO t1 VALUES(8, NULL); } foreach {tn win} { 1 "ORDER BY b RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING" 2 "ORDER BY b RANGE BETWEEN 2 FOLLOWING AND 2 FOLLOWING" 3 "ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING" 4 "ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 2 FOLLOWING" } { do_execsql_test 2.1.$tn " SELECT a, sum(a) OVER win FROM t1 WINDOW win AS ( $win ) ORDER BY 1 " {1 9 2 {} 3 {} 4 9 5 9 6 13 7 13 8 9} } #------------------------------------------------------------------------- ifcapable json1 { reset_db do_execsql_test 3.0 { CREATE TABLE testjson(id INTEGER PRIMARY KEY, j TEXT, x TEXT); INSERT INTO testjson VALUES(1, '{"a":1}', 'a'); INSERT INTO testjson VALUES(2, '{"b":2}', 'b'); INSERT INTO testjson VALUES(3, '{"c":3}', 'c'); INSERT INTO testjson VALUES(4, '{"d":4}', 'd'); } do_execsql_test 3.1 { SELECT json_group_array(json(j)) FROM testjson; } { {[{"a":1},{"b":2},{"c":3},{"d":4}]} } do_execsql_test 3.2 { SELECT json_group_array(json(j)) OVER (ORDER BY id) FROM testjson; } { {[{"a":1}]} {[{"a":1},{"b":2}]} {[{"a":1},{"b":2},{"c":3}]} {[{"a":1},{"b":2},{"c":3},{"d":4}]} } do_execsql_test 3.3 { SELECT json_group_array(json(j)) OVER ( ORDER BY id RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE TIES ) FROM testjson; } { {[{"a":1}]} {[{"a":1},{"b":2}]} {[{"a":1},{"b":2},{"c":3}]} {[{"a":1},{"b":2},{"c":3},{"d":4}]} } do_execsql_test 3.4 { SELECT json_group_array(json(j)) OVER ( ORDER BY id ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) FROM testjson; } { {[{"a":1},{"b":2}]} {[{"a":1},{"b":2},{"c":3}]} {[{"b":2},{"c":3},{"d":4}]} {[{"c":3},{"d":4}]} } do_execsql_test 3.5 { SELECT json_group_array(json(j)) OVER ( ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING ) FROM testjson; } { {[]} {[{"a":1}]} {[{"a":1},{"b":2}]} {[{"b":2},{"c":3}]} } do_execsql_test 3.5a { UPDATE testjson SET j = replace(j,char(125),',"e":9'||char(125)); SELECT j FROM testjson; } { {{"a":1,"e":9}} {{"b":2,"e":9}} {{"c":3,"e":9}} {{"d":4,"e":9}} } do_execsql_test 3.5b { SELECT group_concat(x,'') OVER ( ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING ) FROM testjson ORDER BY id; } {bc cd d {}} do_execsql_test 3.5c { SELECT json_group_array(json(j)) OVER ( ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING ) FROM testjson; } { {[{"b":2,"e":9},{"c":3,"e":9}]} {[{"c":3,"e":9},{"d":4,"e":9}]} {[{"d":4,"e":9}]} {[]} } do_execsql_test 3.5d { SELECT json_group_object(x,json(j)) OVER ( ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING ) FROM testjson; } { {{"b":{"b":2,"e":9},"c":{"c":3,"e":9}}} {{"c":{"c":3,"e":9},"d":{"d":4,"e":9}}} {{"d":{"d":4,"e":9}}} {{}} } do_execsql_test 3.7b { SELECT group_concat(x,'') FILTER (WHERE id!=2) OVER ( ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING ) FROM testjson; } {{} a a c} do_execsql_test 3.7c { SELECT json_group_array(json(j)) FILTER (WHERE id!=2) OVER ( ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING ) FROM testjson } { {[]} {[{"a":1,"e":9}]} {[{"a":1,"e":9}]} {[{"c":3,"e":9}]} } do_execsql_test 3.7d { SELECT json_group_object(x,json(j)) FILTER (WHERE id!=2) OVER ( ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING ) FROM testjson } { {{}} {{"a":{"a":1,"e":9}}} {{"a":{"a":1,"e":9}}} {{"c":{"c":3,"e":9}}} } } #------------------------------------------------------------------------- reset_db do_execsql_test 4.0 { CREATE TABLE x(a); INSERT INTO x VALUES(1); INSERT INTO x VALUES(2); } do_execsql_test 4.1 { WITH y AS ( SELECT Row_Number() OVER (win) FROM x WINDOW win AS (PARTITION BY a) ) SELECT * FROM y; } { 1 1 } do_catchsql_test 4.2 { WITH y AS ( SELECT Row_Number() OVER (win) FROM x WINDOW win AS (PARTITION BY fake_column)) SELECT * FROM y; } {1 {no such column: fake_column}} do_catchsql_test 4.3 { SELECT 1 WINDOW win AS (PARTITION BY fake_column); } {0 1} finish_test |
Changes to test/windowerr.tcl.
︙ | ︙ | |||
60 61 62 63 64 65 66 67 68 69 | WINDOW win AS (ROWS BETWEEN 'hello' PRECEDING AND 10 FOLLOWING) } errorsql_test 3.2 { SELECT sum(a) OVER win FROM t1 WINDOW win AS (ROWS BETWEEN 10 PRECEDING AND x'ABCD' FOLLOWING) } finish_test | > > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 | WINDOW win AS (ROWS BETWEEN 'hello' PRECEDING AND 10 FOLLOWING) } errorsql_test 3.2 { SELECT sum(a) OVER win FROM t1 WINDOW win AS (ROWS BETWEEN 10 PRECEDING AND x'ABCD' FOLLOWING) } errorsql_test 3.3 { SELECT row_number(a) OVER () FROM t1; } finish_test |
Changes to test/windowerr.test.
︙ | ︙ | |||
103 104 105 106 107 108 109 110 111 | } } } 1 # PG says ERROR: argument of ROWS must be type bigint, not type bit do_test 3.2 { catch { execsql { SELECT sum(a) OVER win FROM t1 WINDOW win AS (ROWS BETWEEN 10 PRECEDING AND x'ABCD' FOLLOWING) } } } 1 finish_test | > > > > > | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | } } } 1 # PG says ERROR: argument of ROWS must be type bigint, not type bit do_test 3.2 { catch { execsql { SELECT sum(a) OVER win FROM t1 WINDOW win AS (ROWS BETWEEN 10 PRECEDING AND x'ABCD' FOLLOWING) } } } 1 # PG says ERROR: function row_number(integer) does not exist do_test 3.3 { catch { execsql { SELECT row_number(a) OVER () FROM t1; } } } 1 finish_test |
Changes to test/windowfault.test.
︙ | ︙ | |||
219 220 221 222 223 224 225 226 227 | } } -test { faultsim_test_result [list 0 $::L] } catch {db close} tvfs delete finish_test | > > > > > > > > > > > > > > > > > > > > > > | 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 | } } -test { faultsim_test_result [list 0 $::L] } catch {db close} tvfs delete reset_db do_execsql_test 10.0 { CREATE TABLE t1(a, b, c, d); CREATE TABLE t2(a, b, c, d); } do_faultsim_test 1 -faults oom* -prep { } -body { execsql { SELECT row_number() OVER win FROM t1 WINDOW win AS ( ORDER BY ( SELECT percent_rank() OVER win2 FROM t2 WINDOW win2 AS (ORDER BY a) ) ) } } -test { faultsim_test_result {0 {}} } finish_test |
Changes to test/without_rowid1.test.
︙ | ︙ | |||
26 27 28 29 30 31 32 33 34 35 36 37 38 39 | INSERT INTO t1 VALUES('dynamic','juliet','flipper','command'); INSERT INTO t1 VALUES('journal','sherman','gamma','patriot'); INSERT INTO t1 VALUES('arctic','sleep','ammonia','helena'); SELECT *, '|' FROM t1 ORDER BY c, a; } {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |} integrity_check without_rowid1-1.0ic do_execsql_test without_rowid1-1.1 { SELECT *, '|' FROM t1 ORDER BY +c, a; } {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |} do_execsql_test without_rowid1-1.2 { SELECT *, '|' FROM t1 ORDER BY c DESC, a DESC; | > > > > | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | INSERT INTO t1 VALUES('dynamic','juliet','flipper','command'); INSERT INTO t1 VALUES('journal','sherman','gamma','patriot'); INSERT INTO t1 VALUES('arctic','sleep','ammonia','helena'); SELECT *, '|' FROM t1 ORDER BY c, a; } {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |} integrity_check without_rowid1-1.0ic do_execsql_test without_rowid1-1.0ixi { SELECT name, key FROM pragma_index_xinfo('t1'); } {c 1 a 1 b 0 d 0} do_execsql_test without_rowid1-1.1 { SELECT *, '|' FROM t1 ORDER BY +c, a; } {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |} do_execsql_test without_rowid1-1.2 { SELECT *, '|' FROM t1 ORDER BY c DESC, a DESC; |
︙ | ︙ | |||
94 95 96 97 98 99 100 | # Verify that ANALYZE works # do_execsql_test without_rowid1-1.50 { ANALYZE; SELECT * FROM sqlite_stat1 ORDER BY idx; } {t1 t1 {4 2 1} t1 t1bd {4 2 2}} | < < < < < > > > > > > > > > > > > > > > > > > | 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 | # Verify that ANALYZE works # do_execsql_test without_rowid1-1.50 { ANALYZE; SELECT * FROM sqlite_stat1 ORDER BY idx; } {t1 t1 {4 2 1} t1 t1bd {4 2 2}} ifcapable stat4 { do_execsql_test without_rowid1-1.52 { SELECT DISTINCT tbl, idx FROM sqlite_stat4 ORDER BY idx; } {t1 t1 t1 t1bd} } #---------- do_execsql_test 2.1.1 { CREATE TABLE t4 (a COLLATE nocase PRIMARY KEY, b) WITHOUT ROWID; INSERT INTO t4 VALUES('abc', 'def'); SELECT * FROM t4; } {abc def} do_execsql_test 2.1.2 { UPDATE t4 SET a = 'ABC'; SELECT * FROM t4; } {ABC def} do_execsql_test 2.1.3 { SELECT name, coll, key FROM pragma_index_xinfo('t4'); } {a nocase 1 b BINARY 0} do_execsql_test 2.2.1 { DROP TABLE t4; CREATE TABLE t4 (b, a COLLATE nocase PRIMARY KEY) WITHOUT ROWID; INSERT INTO t4(a, b) VALUES('abc', 'def'); SELECT * FROM t4; } {def abc} do_execsql_test 2.2.2 { UPDATE t4 SET a = 'ABC', b = 'xyz'; SELECT * FROM t4; } {xyz ABC} do_execsql_test 2.2.3 { SELECT name, coll, key FROM pragma_index_xinfo('t4'); } {a nocase 1 b BINARY 0} do_execsql_test 2.3.1 { CREATE TABLE t5 (a, b, PRIMARY KEY(b, a)) WITHOUT ROWID; INSERT INTO t5(a, b) VALUES('abc', 'def'); UPDATE t5 SET a='abc', b='def'; } {} do_execsql_test 2.3.2 { SELECT name, coll, key FROM pragma_index_xinfo('t5'); } {b BINARY 1 a BINARY 1} do_execsql_test 2.4.1 { CREATE TABLE t6 ( a COLLATE nocase, b, c UNIQUE, PRIMARY KEY(b, a) ) WITHOUT ROWID; INSERT INTO t6(a, b, c) VALUES('abc', 'def', 'ghi'); UPDATE t6 SET a='ABC', c='ghi'; } {} do_execsql_test 2.4.2 { SELECT * FROM t6 ORDER BY b, a; SELECT * FROM t6 ORDER BY c; } {ABC def ghi ABC def ghi} do_execsql_test 2.4.3 { SELECT name, coll, key FROM pragma_index_xinfo('t6'); } {b BINARY 1 a nocase 1 c BINARY 0} #------------------------------------------------------------------------- # Unless the destination table is completely empty, the xfer optimization # is disabled for WITHOUT ROWID tables. The following tests check for # some problems that might occur if this were not the case. # reset_db |
︙ | ︙ |
Changes to test/without_rowid6.test.
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | CREATE TABLE t1(a,b,c,d,e, PRIMARY KEY(a,b,c,a,b,c,d,a,b,c)) WITHOUT ROWID; CREATE INDEX t1a ON t1(b, b); WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<1000) INSERT INTO t1(a,b,c,d,e) SELECT i, i+1000, printf('x%dy',i), 0, 0 FROM c; ANALYZE; } {} do_execsql_test without_rowid6-110 { SELECT c FROM t1 WHERE a=123; } {x123y} do_execsql_test without_rowid6-120 { SELECT c FROM t1 WHERE b=1123; } {x123y} do_execsql_test without_rowid6-130 { | > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | CREATE TABLE t1(a,b,c,d,e, PRIMARY KEY(a,b,c,a,b,c,d,a,b,c)) WITHOUT ROWID; CREATE INDEX t1a ON t1(b, b); WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<1000) INSERT INTO t1(a,b,c,d,e) SELECT i, i+1000, printf('x%dy',i), 0, 0 FROM c; ANALYZE; } {} do_execsql_test without_rowid6-101 { SELECT name, key FROM pragma_index_xinfo('t1'); } {a 1 b 1 c 1 d 1 e 0} do_execsql_test without_rowid6-110 { SELECT c FROM t1 WHERE a=123; } {x123y} do_execsql_test without_rowid6-120 { SELECT c FROM t1 WHERE b=1123; } {x123y} do_execsql_test without_rowid6-130 { |
︙ | ︙ | |||
47 48 49 50 51 52 53 54 55 56 57 58 59 60 | b UNIQUE, c UNIQUE, PRIMARY KEY(b) ) WITHOUT ROWID; INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9); SELECT a FROM t1 WHERE b>3 ORDER BY b; } {4 1} do_execsql_test without_rowid6-210 { EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>3 ORDER BY b; } {/SEARCH TABLE t1 USING PRIMARY KEY .b>../} do_execsql_test without_rowid6-220 { PRAGMA index_list(t1); } {/sqlite_autoindex_t1_2 1 pk/} | > > > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | b UNIQUE, c UNIQUE, PRIMARY KEY(b) ) WITHOUT ROWID; INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9); SELECT a FROM t1 WHERE b>3 ORDER BY b; } {4 1} do_execsql_test without_rowid6-201 { SELECT name, key FROM pragma_index_xinfo('t1'); } {b 1 a 0 c 0} do_execsql_test without_rowid6-210 { EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>3 ORDER BY b; } {/SEARCH TABLE t1 USING PRIMARY KEY .b>../} do_execsql_test without_rowid6-220 { PRAGMA index_list(t1); } {/sqlite_autoindex_t1_2 1 pk/} |
︙ | ︙ | |||
101 102 103 104 105 106 107 108 109 110 111 112 113 114 | CREATE TABLE t1(a,b,c, UNIQUE(b,c), PRIMARY KEY(b,c) ) WITHOUT ROWID; INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9); SELECT a FROM t1 WHERE b>3 ORDER BY b; } {4 1} do_execsql_test without_rowid6-510 { EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>3 ORDER BY b; } {/SEARCH TABLE t1 USING PRIMARY KEY .b>../} do_execsql_test without_rowid6-520 { PRAGMA index_list(t1); } {/sqlite_autoindex_t1_1 1 pk/} | > > > | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | CREATE TABLE t1(a,b,c, UNIQUE(b,c), PRIMARY KEY(b,c) ) WITHOUT ROWID; INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9); SELECT a FROM t1 WHERE b>3 ORDER BY b; } {4 1} do_execsql_test without_rowid6-501 { SELECT name, key FROM pragma_index_xinfo('t1'); } {b 1 c 1 a 0} do_execsql_test without_rowid6-510 { EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>3 ORDER BY b; } {/SEARCH TABLE t1 USING PRIMARY KEY .b>../} do_execsql_test without_rowid6-520 { PRAGMA index_list(t1); } {/sqlite_autoindex_t1_1 1 pk/} |
︙ | ︙ |
Added test/without_rowid7.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | # 2019 July 17 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix without_rowid7 do_execsql_test 1.0 { CREATE TABLE t1(a, b COLLATE nocase, PRIMARY KEY(a, a, b)) WITHOUT ROWID; } do_catchsql_test 1.1 { INSERT INTO t1 VALUES(1, 'one'), (1, 'ONE'); } {1 {UNIQUE constraint failed: t1.a, t1.b}} do_execsql_test 2.0 { CREATE TABLE t2(a, b, PRIMARY KEY(a COLLATE nocase, a)) WITHOUT ROWID; } do_execsql_test 2.1 { INSERT INTO t2 VALUES(1, 'one'); SELECT b FROM t2; } {one} do_execsql_test 2.2a { PRAGMA index_info(t2); } {0 0 a 1 0 a} do_execsql_test 2.2b { SELECT *, '|' FROM pragma_index_info('t2'); } {0 0 a | 1 0 a |} do_execsql_test 2.3a { PRAGMA index_xinfo(t2); } {0 0 a 0 nocase 1 1 0 a 0 BINARY 1 2 1 b 0 BINARY 0} do_execsql_test 2.3b { SELECT *, '|' FROM pragma_index_xinfo('t2'); } {0 0 a 0 nocase 1 | 1 0 a 0 BINARY 1 | 2 1 b 0 BINARY 0 |} do_execsql_test 2.4 { CREATE TABLE t3(a, b, PRIMARY KEY(a COLLATE nocase, a)); PRAGMA index_info(t3); } {} finish_test |
Changes to tool/lemon.c.
︙ | ︙ | |||
4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 | char line[LINESIZE]; int lineno; struct state *stp; struct action *ap; struct rule *rp; struct acttab *pActtab; int i, j, n, sz; int szActionType; /* sizeof(YYACTIONTYPE) */ int szCodeType; /* sizeof(YYCODETYPE) */ const char *name; int mnTknOfst, mxTknOfst; int mnNtOfst, mxNtOfst; struct axset *ax; | > | 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 | char line[LINESIZE]; int lineno; struct state *stp; struct action *ap; struct rule *rp; struct acttab *pActtab; int i, j, n, sz; int nLookAhead; int szActionType; /* sizeof(YYACTIONTYPE) */ int szCodeType; /* sizeof(YYCODETYPE) */ const char *name; int mnTknOfst, mxTknOfst; int mnNtOfst, mxNtOfst; struct axset *ax; |
︙ | ︙ | |||
4399 4400 4401 4402 4403 4404 4405 | lemp->tablesize += n*szCodeType; fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++; for(i=j=0; i<n; i++){ int la = acttab_yylookahead(pActtab, i); if( la<0 ) la = lemp->nsymbol; if( j==0 ) fprintf(out," /* %5d */ ", i); fprintf(out, " %4d,", la); | | > > > > > > > > > > > > > > > > | 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 | lemp->tablesize += n*szCodeType; fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++; for(i=j=0; i<n; i++){ int la = acttab_yylookahead(pActtab, i); if( la<0 ) la = lemp->nsymbol; if( j==0 ) fprintf(out," /* %5d */ ", i); fprintf(out, " %4d,", la); if( j==9 ){ fprintf(out, "\n"); lineno++; j = 0; }else{ j++; } } /* Add extra entries to the end of the yy_lookahead[] table so that ** yy_shift_ofst[]+iToken will always be a valid index into the array, ** even for the largest possible value of yy_shift_ofst[] and iToken. */ nLookAhead = lemp->nterminal + lemp->nactiontab; while( i<nLookAhead ){ if( j==0 ) fprintf(out," /* %5d */ ", i); fprintf(out, " %4d,", lemp->nterminal); if( j==9 ){ fprintf(out, "\n"); lineno++; j = 0; }else{ j++; } i++; } if( j>0 ){ fprintf(out, "\n"); lineno++; } fprintf(out, "};\n"); lineno++; /* Output the yy_shift_ofst[] table */ n = lemp->nxstate; while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--; fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++; fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++; |
︙ | ︙ | |||
4485 4486 4487 4488 4489 4490 4491 | fprintf(out, "};\n"); lineno++; tplt_xfer(lemp->name,in,out,&lineno); /* Generate the table of fallback tokens. */ if( lemp->has_fallback ){ int mx = lemp->nterminal - 1; | > > | | 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 | fprintf(out, "};\n"); lineno++; tplt_xfer(lemp->name,in,out,&lineno); /* Generate the table of fallback tokens. */ if( lemp->has_fallback ){ int mx = lemp->nterminal - 1; /* 2019-08-28: Generate fallback entries for every token to avoid ** having to do a range check on the index */ /* while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; } */ lemp->tablesize += (mx+1)*szCodeType; for(i=0; i<=mx; i++){ struct symbol *p = lemp->symbols[i]; if( p->fallback==0 ){ fprintf(out, " 0, /* %10s => nothing */\n", p->name); }else{ fprintf(out, " %3d, /* %10s => %s */\n", p->fallback->index, |
︙ | ︙ |
Changes to tool/lempar.c.
︙ | ︙ | |||
517 518 519 520 521 522 523 | assert( stateno <= YY_SHIFT_COUNT ); #if defined(YYCOVERAGE) yycoverage[stateno][iLookAhead] = 1; #endif do{ i = yy_shift_ofst[stateno]; assert( i>=0 ); | > | > | | | > < < < < < < < | | < > | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 | assert( stateno <= YY_SHIFT_COUNT ); #if defined(YYCOVERAGE) yycoverage[stateno][iLookAhead] = 1; #endif do{ i = yy_shift_ofst[stateno]; assert( i>=0 ); assert( i<=YY_ACTTAB_COUNT ); assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); assert( iLookAhead!=YYNOCODE ); assert( iLookAhead < YYNTOKEN ); i += iLookAhead; assert( i<(int)YY_NLOOKAHEAD ); if( yy_lookahead[i]!=iLookAhead ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ assert( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0]) ); iFallback = yyFallback[iLookAhead]; if( iFallback!=0 ){ #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n", yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); } #endif assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */ iLookAhead = iFallback; continue; } #endif #ifdef YYWILDCARD { int j = i - iLookAhead + YYWILDCARD; assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) ); if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){ #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); } #endif /* NDEBUG */ return yy_action[j]; } } #endif /* YYWILDCARD */ return yy_default[stateno]; }else{ assert( i>=0 && i<sizeof(yy_action)/sizeof(yy_action[0]) ); return yy_action[i]; } }while(1); } /* ** Find the appropriate action for a parser given the non-terminal |
︙ | ︙ | |||
1064 1065 1066 1067 1068 1069 1070 | /* ** Return the fallback token corresponding to canonical token iToken, or ** 0 if iToken has no fallback. */ int ParseFallback(int iToken){ #ifdef YYFALLBACK | | | < | 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 | /* ** Return the fallback token corresponding to canonical token iToken, or ** 0 if iToken has no fallback. */ int ParseFallback(int iToken){ #ifdef YYFALLBACK assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ); return yyFallback[iToken]; #else (void)iToken; #endif return 0; } |
Changes to tool/mkkeywordhash.c.
︙ | ︙ | |||
205 206 207 208 209 210 211 212 213 214 215 216 217 218 | { "ESCAPE", "TK_ESCAPE", ALWAYS }, { "EXCEPT", "TK_EXCEPT", COMPOUND }, { "EXCLUDE", "TK_EXCLUDE", WINDOWFUNC }, { "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 }, { "FULL", "TK_JOIN_KW", ALWAYS }, { "GLOB", "TK_LIKE_KW", ALWAYS }, { "GROUP", "TK_GROUP", ALWAYS }, | > | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | { "ESCAPE", "TK_ESCAPE", ALWAYS }, { "EXCEPT", "TK_EXCEPT", COMPOUND }, { "EXCLUDE", "TK_EXCLUDE", WINDOWFUNC }, { "EXISTS", "TK_EXISTS", ALWAYS }, { "EXPLAIN", "TK_EXPLAIN", EXPLAIN }, { "FAIL", "TK_FAIL", CONFLICT|TRIGGER }, { "FILTER", "TK_FILTER", WINDOWFUNC }, { "FIRST", "TK_FIRST", ALWAYS }, { "FOLLOWING", "TK_FOLLOWING", WINDOWFUNC }, { "FOR", "TK_FOR", TRIGGER }, { "FOREIGN", "TK_FOREIGN", FKEY }, { "FROM", "TK_FROM", ALWAYS }, { "FULL", "TK_JOIN_KW", ALWAYS }, { "GLOB", "TK_LIKE_KW", ALWAYS }, { "GROUP", "TK_GROUP", ALWAYS }, |
︙ | ︙ | |||
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | { "INSTEAD", "TK_INSTEAD", TRIGGER }, { "INTERSECT", "TK_INTERSECT", COMPOUND }, { "INTO", "TK_INTO", ALWAYS }, { "IS", "TK_IS", ALWAYS }, { "ISNULL", "TK_ISNULL", ALWAYS }, { "JOIN", "TK_JOIN", ALWAYS }, { "KEY", "TK_KEY", ALWAYS }, { "LEFT", "TK_JOIN_KW", ALWAYS }, { "LIKE", "TK_LIKE_KW", ALWAYS }, { "LIMIT", "TK_LIMIT", ALWAYS }, { "MATCH", "TK_MATCH", ALWAYS }, { "NATURAL", "TK_JOIN_KW", ALWAYS }, { "NO", "TK_NO", FKEY|WINDOWFUNC }, { "NOT", "TK_NOT", ALWAYS }, { "NOTHING", "TK_NOTHING", UPSERT }, { "NOTNULL", "TK_NOTNULL", ALWAYS }, { "NULL", "TK_NULL", ALWAYS }, { "OF", "TK_OF", ALWAYS }, { "OFFSET", "TK_OFFSET", ALWAYS }, { "ON", "TK_ON", ALWAYS }, { "OR", "TK_OR", ALWAYS }, { "ORDER", "TK_ORDER", ALWAYS }, { "OTHERS", "TK_OTHERS", WINDOWFUNC }, { "OUTER", "TK_JOIN_KW", ALWAYS }, | > > | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | { "INSTEAD", "TK_INSTEAD", TRIGGER }, { "INTERSECT", "TK_INTERSECT", COMPOUND }, { "INTO", "TK_INTO", ALWAYS }, { "IS", "TK_IS", ALWAYS }, { "ISNULL", "TK_ISNULL", ALWAYS }, { "JOIN", "TK_JOIN", ALWAYS }, { "KEY", "TK_KEY", ALWAYS }, { "LAST", "TK_LAST", ALWAYS }, { "LEFT", "TK_JOIN_KW", ALWAYS }, { "LIKE", "TK_LIKE_KW", ALWAYS }, { "LIMIT", "TK_LIMIT", ALWAYS }, { "MATCH", "TK_MATCH", ALWAYS }, { "NATURAL", "TK_JOIN_KW", ALWAYS }, { "NO", "TK_NO", FKEY|WINDOWFUNC }, { "NOT", "TK_NOT", ALWAYS }, { "NOTHING", "TK_NOTHING", UPSERT }, { "NOTNULL", "TK_NOTNULL", ALWAYS }, { "NULL", "TK_NULL", ALWAYS }, { "NULLS", "TK_NULLS", ALWAYS }, { "OF", "TK_OF", ALWAYS }, { "OFFSET", "TK_OFFSET", ALWAYS }, { "ON", "TK_ON", ALWAYS }, { "OR", "TK_OR", ALWAYS }, { "ORDER", "TK_ORDER", ALWAYS }, { "OTHERS", "TK_OTHERS", WINDOWFUNC }, { "OUTER", "TK_JOIN_KW", ALWAYS }, |
︙ | ︙ |
Changes to tool/mkpragmatab.tcl.
︙ | ︙ | |||
266 267 268 269 270 271 272 | COLS: seq name file IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: function_list FLAG: Result0 COLS: name builtin IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) | | | | | 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | COLS: seq name file IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: function_list FLAG: Result0 COLS: name builtin IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) IF: !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) NAME: module_list FLAG: Result0 COLS: name IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) IF: !defined(SQLITE_OMIT_VIRTUALTABLE) IF: !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) NAME: pragma_list FLAG: Result0 COLS: name IF: !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) NAME: collation_list FLAG: Result0 COLS: seq name IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: foreign_key_list |
︙ | ︙ |