Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch typos Excluding Merge-Ins
This is equivalent to a diff from ee8a1080 to a80ae2c9
2020-07-30
| ||
17:29 | Allow for page numbers as large as 4294967294 (0xfffffffe) which means database files as large as 281 TB. (check-in: 166e82dd user: drh tags: trunk) | |
2020-07-29
| ||
16:18 | Dozens and dozens of typo fixes in comments. This change adds no value to the end product and is disruptive, so it is questionable whether or not it will ever land on trunk. (Leaf check-in: a80ae2c9 user: drh tags: typos) | |
2020-07-28
| ||
17:51 | Merge enhancements from trunk. (check-in: 969c25bb user: drh tags: larger-databases) | |
17:29 | If a writer crashes in WAL mode and leave the SHM file in an inconsistent state, subsequent transactions are now able to recover the SHM file even if there are active read transactions. (check-in: ee8a1080 user: drh tags: trunk) | |
17:17 | Add an sqlite3FaultSim() to make an OOM case more accessible and remove the ALWAYS() on the conditional that is false when the OOM actually occurs. (Closed-Leaf check-in: 2a251af8 user: drh tags: unlocked-recovery) | |
2020-07-24
| ||
11:01 | Remove a surplus space from a comment (check-in: 73fecc68 user: drh tags: trunk) | |
Changes to Makefile.in.
︙ | ︙ | |||
82 83 84 85 86 87 88 | # based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*). # The same set of OMIT and ENABLE flags should be passed to the # LEMON parser generator and the mkkeywordhash tool as well. OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ TCC += $(OPT_FEATURE_FLAGS) | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | # based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*). # The same set of OMIT and ENABLE flags should be passed to the # LEMON parser generator and the mkkeywordhash tool as well. OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ TCC += $(OPT_FEATURE_FLAGS) # Add in any optional parameters specified on the make command line # ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". TCC += $(OPTS) # Add in compile-time options for some libraries used by extensions TCC += @HAVE_ZLIB@ # Version numbers and release number for the SQLite being compiled. |
︙ | ︙ |
Changes to Makefile.msc.
︙ | ︙ | |||
1029 1030 1031 1032 1033 1034 1035 | # Add the required and optional SQLite compilation options into the command # lines used to invoke the MSVC code and resource compilers. # TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) | | | 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 | # Add the required and optional SQLite compilation options into the command # lines used to invoke the MSVC code and resource compilers. # TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) # Add in any optional parameters specified on the command line, e.g. # nmake /f Makefile.msc all "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1" # TCC = $(TCC) $(OPTS) RCC = $(RCC) $(OPTS) # If compiling for debugging, add some defines. # |
︙ | ︙ |
Changes to README.md.
︙ | ︙ | |||
11 12 13 14 15 16 17 | [Fossil](https://www.fossil-scm.org/), a distributed version control system that was specifically designed and written to support SQLite development. The [Fossil repository](https://sqlite.org/src/timeline) contains the urtext. If you are reading this on GitHub or some other Git repository or service, then you are looking at a mirror. The names of check-ins and other artifacts in a Git mirror are different from the official | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | [Fossil](https://www.fossil-scm.org/), a distributed version control system that was specifically designed and written to support SQLite development. The [Fossil repository](https://sqlite.org/src/timeline) contains the urtext. If you are reading this on GitHub or some other Git repository or service, then you are looking at a mirror. The names of check-ins and other artifacts in a Git mirror are different from the official names for those objects. The official names for check-ins are found in a footer on the check-in comment for authorized mirrors. The official check-in name can also be seen in the `manifest.uuid` file in the root of the tree. Always use the official name, not the Git-name, when communicating about an SQLite check-in. If you pulled your SQLite source code from a secondary source and want to verify its integrity, there are hints on how to do that in the |
︙ | ︙ | |||
132 133 134 135 136 137 138 | [command-line shell](https://sqlite.org/cli.html) and the "tclsqlite.c" file which implements the [Tcl bindings](https://sqlite.org/tclsqlite.html) for SQLite. (Historical note: SQLite began as a Tcl extension and only later escaped to the wild as an independent library.) Test scripts and programs are found in the **test/** subdirectory. | | | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | [command-line shell](https://sqlite.org/cli.html) and the "tclsqlite.c" file which implements the [Tcl bindings](https://sqlite.org/tclsqlite.html) for SQLite. (Historical note: SQLite began as a Tcl extension and only later escaped to the wild as an independent library.) Test scripts and programs are found in the **test/** subdirectory. Additional test code is found in other source repositories. See [How SQLite Is Tested](http://www.sqlite.org/testing.html) for additional information. The **ext/** subdirectory contains code for extensions. The Full-text search engine is in **ext/fts3**. The R-Tree engine is in **ext/rtree**. The **ext/misc** subdirectory contains a number of smaller, single-file extensions, such as a REGEXP operator. |
︙ | ︙ | |||
233 234 235 236 237 238 239 | (helping to understand how SQLite works include the [file format](http://www.sqlite.org/fileformat2.html) description, the [virtual machine](http://www.sqlite.org/opcode.html) that runs prepared statements, the description of [how transactions work](http://www.sqlite.org/atomiccommit.html), and the [overview of the query planner](http://www.sqlite.org/optoverview.html). | | | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | (helping to understand how SQLite works include the [file format](http://www.sqlite.org/fileformat2.html) description, the [virtual machine](http://www.sqlite.org/opcode.html) that runs prepared statements, the description of [how transactions work](http://www.sqlite.org/atomiccommit.html), and the [overview of the query planner](http://www.sqlite.org/optoverview.html). Years of effort have gone into optimizing SQLite, both for small size and high performance. And optimizations tend to result in complex code. So there is a lot of complexity in the current SQLite implementation. It will not be the easiest library in the world to hack. Key files: * **sqlite.h.in** - This file defines the public interface to the SQLite |
︙ | ︙ |
Changes to aclocal.m4.
︙ | ︙ | |||
7965 7966 7967 7968 7969 7970 7971 | m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) | < | 7965 7966 7967 7968 7969 7970 7971 | m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) |
Changes to autoconf/INSTALL.
︙ | ︙ | |||
363 364 365 366 367 368 369 | `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. | < | 363 364 365 366 367 368 369 | `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. |
Changes to autoconf/Makefile.msc.
︙ | ︙ | |||
772 773 774 775 776 777 778 | # Add the required and optional SQLite compilation options into the command # lines used to invoke the MSVC code and resource compilers. # TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) | | | 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 | # Add the required and optional SQLite compilation options into the command # lines used to invoke the MSVC code and resource compilers. # TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) # Add in any optional parameters specified on the command line, e.g. # nmake /f Makefile.msc all "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1" # TCC = $(TCC) $(OPTS) RCC = $(RCC) $(OPTS) # If compiling for debugging, add some defines. # |
︙ | ︙ |
Changes to autoconf/README.txt.
1 2 3 4 5 6 | This package contains: * the SQLite library amalgamation source code file: sqlite3.c * the sqlite3.h and sqlite3ext.h header files that define the C-language interface to the sqlite3.c library file * the shell.c file used to build the sqlite3 command-line shell program | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | This package contains: * the SQLite library amalgamation source code file: sqlite3.c * the sqlite3.h and sqlite3ext.h header files that define the C-language interface to the sqlite3.c library file * the shell.c file used to build the sqlite3 command-line shell program * autoconf/automake installation infrastructure for building on POSIX compliant systems * a Makefile.msc, sqlite3.rc, and Replace.cs for building with Microsoft Visual C++ on Windows SUMMARY OF HOW TO BUILD ======================= |
︙ | ︙ |
Changes to autoconf/tea/Makefile.in.
︙ | ︙ | |||
170 171 172 173 174 175 176 | #======================================================================== # Start of user-definable TARGETS section #======================================================================== #======================================================================== # TEA TARGETS. Please note that the "libraries:" target refers to platform | | | | 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | #======================================================================== # Start of user-definable TARGETS section #======================================================================== #======================================================================== # TEA TARGETS. Please note that the "libraries:" target refers to platform # independent files, and the "binaries:" target includes executable programs # and platform-dependent libraries. Modify these targets so that they install # the various pieces of your package. The make and install rules # for the BINARIES that you specified above have already been done. #======================================================================== all: binaries libraries doc #======================================================================== |
︙ | ︙ |
Changes to autoconf/tea/configure.ac.
︙ | ︙ | |||
82 83 84 85 86 87 88 | TEA_ADD_TCL_SOURCES([]) #-------------------------------------------------------------------- # The --with-system-sqlite causes the TCL bindings to SQLite to use # the system shared library for SQLite rather than statically linking # against its own private copy. This is dangerous and leads to # undersirable dependences and is not recommended. | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | TEA_ADD_TCL_SOURCES([]) #-------------------------------------------------------------------- # The --with-system-sqlite causes the TCL bindings to SQLite to use # the system shared library for SQLite rather than statically linking # against its own private copy. This is dangerous and leads to # undersirable dependences and is not recommended. # Patches from rmax. #-------------------------------------------------------------------- AC_ARG_WITH([system-sqlite], [AC_HELP_STRING([--with-system-sqlite], [use a system-supplied libsqlite3 instead of the bundled one])], [], [with_system_sqlite=no]) if test x$with_system_sqlite != xno; then AC_CHECK_HEADER([sqlite3.h], |
︙ | ︙ |
Changes to autoconf/tea/win/nmakehlp.c.
︙ | ︙ | |||
200 201 202 203 204 205 206 | ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = FALSE; /* | | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = FALSE; /* * Create a non-inheritable pipe. */ CreatePipe(&Out.pipe, &h, &sa, 0); /* * Dupe the write side, make it inheritable, and close the original. */ DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); /* * Same as above, but for the error side. |
︙ | ︙ | |||
334 335 336 337 338 339 340 | ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* | | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* * Create a non-inheritable pipe. */ CreatePipe(&Out.pipe, &h, &sa, 0); /* * Dupe the write side, make it inheritable, and close the original. */ DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); /* * Same as above, but for the error side. |
︙ | ︙ |
Changes to autoconf/tea/win/rules.vc.
︙ | ︙ | |||
704 705 706 707 708 709 710 | !message *** Optional defines are '$(OPTDEFINES)' !message *** Compiler version $(VCVER). Target machine is $(MACHINE) !message *** Host architecture is $(NATIVE_ARCH) !message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)' !message *** Link options '$(LINKERFLAGS)' !endif | < | 704 705 706 707 708 709 710 | !message *** Optional defines are '$(OPTDEFINES)' !message *** Compiler version $(VCVER). Target machine is $(MACHINE) !message *** Host architecture is $(NATIVE_ARCH) !message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)' !message *** Link options '$(LINKERFLAGS)' !endif |
Changes to configure.
︙ | ︙ | |||
13917 13918 13919 13920 13921 13922 13923 | # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi | < | 13917 13918 13919 13920 13921 13922 13923 | # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi |
Changes to contrib/sqlitecon.tcl.
︙ | ︙ | |||
442 443 444 445 446 447 448 | if {$px==$ix} { $w mark set insert $p } $w mark set anchor $p focus $w } | | | 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 | if {$px==$ix} { $w mark set insert $p } $w mark set anchor $p focus $w } # Find the boundary between characters that is nearest # to $x,$y # proc sqlitecon::nearestBoundry {w x y} { set p [$w index @$x,$y] set bb [$w bbox $p] if {![string compare $bb ""]} {return $p} if {($x-[lindex $bb 0])<([lindex $bb 2]/2)} {return $p} |
︙ | ︙ | |||
563 564 565 566 567 568 569 | proc sqlitecon::Cut w { if {[sqlitecon::canCut $w]==1} { sqlitecon::Copy $w $w delete sel.first sel.last } } | | | 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 | proc sqlitecon::Cut w { if {[sqlitecon::canCut $w]==1} { sqlitecon::Copy $w $w delete sel.first sel.last } } # Do a paste operation. # proc sqlitecon::Paste w { if {[sqlitecon::canCut $w]==1} { $w delete sel.first sel.last } if {[catch {selection get -displayof $w -selection CLIPBOARD} topaste] && [catch {selection get -displayof $w -selection PRIMARY} topaste]} { |
︙ | ︙ |
Changes to doc/F2FS.txt.
︙ | ︙ | |||
77 78 79 80 81 82 83 | 3. If the process crashes before the F2FS_IOC_COMMIT_ATOMIC_WRITE is completed then the file is automatically restored to the state that it was in before F2FS_IOC_START_ATOMIC_WRITE was called. This occurs before the posix advisory lock is automatically dropped - there is no chance that another client will be able to read the file in a half-committed state before the rollback operation occurs. | < < < < | 77 78 79 80 81 82 83 | 3. If the process crashes before the F2FS_IOC_COMMIT_ATOMIC_WRITE is completed then the file is automatically restored to the state that it was in before F2FS_IOC_START_ATOMIC_WRITE was called. This occurs before the posix advisory lock is automatically dropped - there is no chance that another client will be able to read the file in a half-committed state before the rollback operation occurs. |
Changes to doc/lemon.html.
︙ | ︙ | |||
692 693 694 695 696 697 698 | is passed in on the ParseAlloc() or ParseInit() routines instead of on Parse(). <a name='extractx'></a> <h4>The <tt>%extra_context</tt> directive</h4> The <tt>%extra_context</tt> directive instructs Lemon to add a 2nd parameter | | | 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 | is passed in on the ParseAlloc() or ParseInit() routines instead of on Parse(). <a name='extractx'></a> <h4>The <tt>%extra_context</tt> directive</h4> The <tt>%extra_context</tt> directive instructs Lemon to add a 2nd parameter to the parameter list of the ParseAlloc() and ParseInit() functions. Lemon doesn't do anything itself with these extra argument, but it does store the value make it available to C-code action routines, destructors, and so forth. For example, if the grammar file contains:</p> <p><pre> %extra_context { MyStruct *pAbc } </pre></p> |
︙ | ︙ | |||
751 752 753 754 755 756 757 | just not as general. Each of these directives must begin at the left margin. No whitespace is allowed between the "%" and the directive name.</p> <p>Grammar text in between "<tt>%ifdef MACRO</tt>" and the next nested "<tt>%endif</tt>" is ignored unless the "-DMACRO" command-line option is used. Grammar text | | | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | just not as general. Each of these directives must begin at the left margin. No whitespace is allowed between the "%" and the directive name.</p> <p>Grammar text in between "<tt>%ifdef MACRO</tt>" and the next nested "<tt>%endif</tt>" is ignored unless the "-DMACRO" command-line option is used. Grammar text between "<tt>%ifndef MACRO</tt>" and the next nested "<tt>%endif</tt>" is included except when the "-DMACRO" command-line option is used.<p> <p>The text in between "<tt>%if</tt> <i>CONDITIONAL</i>" and its corresponding <tt>%endif</tt> is included only if <i>CONDITIONAL</i> is true. The CONDITION is one or more macro names, optionally connected using the "||" and "&&" binary operators, the "!" unary operator, and grouped using balanced parentheses. Each term is true if the |
︙ | ︙ |
Changes to doc/pager-invariants.txt.
1 2 3 4 5 | *** Throughout this document, a page is deemed to have been synced automatically as soon as it is written when PRAGMA synchronous=OFF. Otherwise, the page is not synced until the xSync method of the VFS is called successfully on the file containing the page. | | | | 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 | *** Throughout this document, a page is deemed to have been synced automatically as soon as it is written when PRAGMA synchronous=OFF. Otherwise, the page is not synced until the xSync method of the VFS is called successfully on the file containing the page. *** Definition: A page of the database file is said to be "overwritable" if one or more of the following are true about the page: (a) The original content of the page as it was at the beginning of the transaction has been written into the rollback journal and synced. (b) The page was a freelist leaf page at the start of the transaction. (c) The page number is greater than the largest page that existed in the database file at the start of the transaction. (1) A page of the database file is never overwritten unless one of the following are true: (a) The page and all other pages on the same sector are overwritable. (b) The atomic page write optimization is enabled, and the entire transaction other than the update of the transaction sequence number consists of a single page change. (2) The content of a page written into the rollback journal exactly matches both the content in the database when the rollback journal was written |
︙ | ︙ | |||
41 42 43 44 45 46 47 | (6) If a master journal file is used, then all writes to the database file are synced prior to the master journal being deleted. *** Definition: Two databases (or the same database at two points it time) are said to be "logically equivalent" if they give the same answer to all queries. Note in particular the content of freelist leaf | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | (6) If a master journal file is used, then all writes to the database file are synced prior to the master journal being deleted. *** Definition: Two databases (or the same database at two points it time) are said to be "logically equivalent" if they give the same answer to all queries. Note in particular the content of freelist leaf pages can be changed arbitrarily without effecting the logical equivalence of the database. (7) At any time, if any subset, including the empty set and the total set, of the unsynced changes to a rollback journal are removed and the journal is rolled back, the resulting database file will be logical equivalent to the database file at the beginning of the transaction. |
︙ | ︙ |
Changes to doc/vfs-shm.txt.
︙ | ︙ | |||
54 55 56 57 58 59 60 | RECOVER - Held during wal-index recovery. Used to prevent a race if multiple clients try to recover a wal-index at the same time. A particular lock manager implementation may coalesce one or more of the wal-index locking states, though with a reduction in concurrency. | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | RECOVER - Held during wal-index recovery. Used to prevent a race if multiple clients try to recover a wal-index at the same time. A particular lock manager implementation may coalesce one or more of the wal-index locking states, though with a reduction in concurrency. For example, an implementation might implement only exclusive locking, in which case all states would be equivalent to CHECKPOINT, meaning that only one reader or one writer or one checkpointer could be active at a time. Or, an implementation might combine READ and READ_FULL into a single state equivalent to READ, meaning that a writer could coexist with a reader, but no reader or writers could coexist with a checkpointer. |
︙ | ︙ |
Changes to doc/wal-lock.md.
︙ | ︙ | |||
80 81 82 83 84 85 86 | * when an open read-transaction is upgraded to a write-transaction. In all other cases the blocking locks implementation should prevent clients from having to handle SQLITE\_BUSY errors and facilitate appropriate transfer of priorities between competing clients. Clients that lock multiple databases simultaneously must be wary of deadlock. | < < | 80 81 82 83 84 85 86 | * when an open read-transaction is upgraded to a write-transaction. In all other cases the blocking locks implementation should prevent clients from having to handle SQLITE\_BUSY errors and facilitate appropriate transfer of priorities between competing clients. Clients that lock multiple databases simultaneously must be wary of deadlock. |
Changes to ext/async/README.txt.
︙ | ︙ | |||
43 44 45 46 47 48 49 | your program crashes or if a power loss occurs after the database write but before the asynchronous write thread has completed, then the database change might never make it to disk and the next user of the database might not see your change. You lose Durability with asynchronous I/O, but you still retain the other parts of ACID: Atomic, Consistent, and Isolated. Many | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | your program crashes or if a power loss occurs after the database write but before the asynchronous write thread has completed, then the database change might never make it to disk and the next user of the database might not see your change. You lose Durability with asynchronous I/O, but you still retain the other parts of ACID: Atomic, Consistent, and Isolated. Many applications get along fine without the Durability. 1.1 How it Works Asynchronous I/O works by creating a special SQLite "vfs" structure and registering it with sqlite3_vfs_register(). When files opened via this vfs are written to (using the vfs xWrite() method), the data is not written directly to disk, but is placed in the "write-queue" to be |
︙ | ︙ |
Changes to ext/async/sqlite3async.c.
︙ | ︙ | |||
1325 1326 1327 1328 1329 1330 1331 | ** If async.writerHaltNow is true, then this procedure exits ** after processing a single message. ** ** If async.writerHaltWhenIdle is true, then this procedure exits when ** the write queue is empty. ** ** If both of the above variables are false, this procedure runs | | | | 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 | ** If async.writerHaltNow is true, then this procedure exits ** after processing a single message. ** ** If async.writerHaltWhenIdle is true, then this procedure exits when ** the write queue is empty. ** ** If both of the above variables are false, this procedure runs ** indefinitely, waiting for operations to be added to the write queue ** and processing them in the order in which they arrive. ** ** An artificial delay of async.ioDelay milliseconds is inserted before ** each write operation in order to simulate the effect of a slow disk. ** ** Only one instance of this procedure may be running at a time. */ static void asyncWriterThread(void){ sqlite3_vfs *pVfs = (sqlite3_vfs *)(async_vfs.pAppData); AsyncWrite *p = 0; |
︙ | ︙ | |||
1374 1375 1376 1377 1378 1379 1380 | ** perform the IO, and then re-request the mutex before removing 'p' from ** the head of the write-op queue. The idea is to increase concurrency with ** sqlite threads. ** ** * An ASYNC_CLOSE operation. ** * An ASYNC_OPENEXCLUSIVE operation. For this one, we relinquish ** the mutex, call the underlying xOpenExclusive() function, then | | | 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 | ** perform the IO, and then re-request the mutex before removing 'p' from ** the head of the write-op queue. The idea is to increase concurrency with ** sqlite threads. ** ** * An ASYNC_CLOSE operation. ** * An ASYNC_OPENEXCLUSIVE operation. For this one, we relinquish ** the mutex, call the underlying xOpenExclusive() function, then ** re-acquire the mutex before setting the AsyncFile.pBaseRead ** variable. ** * ASYNC_SYNC and ASYNC_WRITE operations, if ** SQLITE_ASYNC_TWO_FILEHANDLES was set at compile time and two ** file-handles are open for the particular file being "synced". */ if( async.ioError!=SQLITE_OK && p->op!=ASYNC_CLOSE ){ p->op = ASYNC_NOOP; |
︙ | ︙ |
Changes to ext/async/sqlite3async.h.
︙ | ︙ | |||
57 58 59 60 61 62 63 | ** ** If a parent VFS cannot be located, then SQLITE_ERROR is returned. ** In the unlikely event that operating system specific initialization ** fails (win32 systems create the required critical section and event ** objects within this function), then SQLITE_ERROR is also returned. ** Finally, if the call to sqlite3_vfs_register() returns an error, then ** the error code is returned to the user by this function. In all three | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | ** ** If a parent VFS cannot be located, then SQLITE_ERROR is returned. ** In the unlikely event that operating system specific initialization ** fails (win32 systems create the required critical section and event ** objects within this function), then SQLITE_ERROR is also returned. ** Finally, if the call to sqlite3_vfs_register() returns an error, then ** the error code is returned to the user by this function. In all three ** of these cases, initialization has failed and the asynchronous IO VFS ** is not registered with SQLite. ** ** Otherwise, if no error occurs, SQLITE_OK is returned. */ int sqlite3async_initialize(const char *zParent, int isDefault); /* |
︙ | ︙ |
Changes to ext/expert/sqlite3expert.c.
︙ | ︙ | |||
1780 1781 1782 1783 1784 1785 1786 | } /* Register the auth callback with dbv */ if( rc==SQLITE_OK ){ sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew); } | | | 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 | } /* Register the auth callback with dbv */ if( rc==SQLITE_OK ){ sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew); } /* If an error has occurred, free the new object and return NULL. Otherwise, ** return the new sqlite3expert handle. */ if( rc!=SQLITE_OK ){ sqlite3_expert_destroy(pNew); pNew = 0; } return pNew; } |
︙ | ︙ |
Changes to ext/expert/sqlite3expert.h.
︙ | ︙ | |||
132 133 134 135 136 137 138 | ** along with such an EXPERT_REPORT_* parameter, NULL is always returned. ** ** EXPERT_REPORT_SQL: ** Return the text of SQL statement iStmt. ** ** EXPERT_REPORT_INDEXES: ** Return a buffer containing the CREATE INDEX statements for all recommended | | | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | ** along with such an EXPERT_REPORT_* parameter, NULL is always returned. ** ** EXPERT_REPORT_SQL: ** Return the text of SQL statement iStmt. ** ** EXPERT_REPORT_INDEXES: ** Return a buffer containing the CREATE INDEX statements for all recommended ** indexes for statement iStmt. If there are no new recommended indexes, NULL ** is returned. ** ** EXPERT_REPORT_PLAN: ** Return a buffer containing the EXPLAIN QUERY PLAN output for SQL query ** iStmt after the proposed indexes have been added to the database schema. ** ** EXPERT_REPORT_CANDIDATES: |
︙ | ︙ |
Changes to ext/fts1/ft_hash.c.
︙ | ︙ | |||
139 140 141 142 143 144 145 | if( n1!=n2 ) return 1; return memcmp(pKey1,pKey2,n1); } /* ** Return a pointer to the appropriate hash function given the key class. ** | | | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | if( n1!=n2 ) return 1; return memcmp(pKey1,pKey2,n1); } /* ** Return a pointer to the appropriate hash function given the key class. ** ** The C syntax in this function definition may be unfamiliar to some ** programmers, so we provide the following additional explanation: ** ** The name of the function is "hashFunction". The function takes a ** single parameter "keyClass". The return value of hashFunction() ** is a pointer to another function. Specifically, the return value ** of hashFunction() is a pointer to a function that takes two parameters ** with types "const void*" and "int" and returns an "int". |
︙ | ︙ | |||
220 221 222 223 224 225 226 | pH->first = pNew; } pEntry->count++; pEntry->chain = pNew; } | | | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | pH->first = pNew; } pEntry->count++; pEntry->chain = pNew; } /* Resize the hash table so that it contains "new_size" buckets. ** "new_size" must be a power of 2. The hash table might fail ** to resize if sqliteMalloc() fails. */ static void rehash(Hash *pH, int new_size){ struct _ht *new_ht; /* The new hash table */ HashElem *elem, *next_elem; /* For looping over existing elements */ int (*xHash)(const void*,int); /* The hash function */ |
︙ | ︙ |
Changes to ext/fts1/fts1.c.
︙ | ︙ | |||
1539 1540 1541 1542 1543 1544 1545 | ** IdChar(X) will be true. Otherwise it is false. ** ** For ASCII, any character with the high-order bit set is ** allowed in an identifier. For 7-bit characters, ** sqlite3IsIdChar[X] must be 1. ** ** Ticket #1066. the SQL standard does not allow '$' in the | | | 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 | ** IdChar(X) will be true. Otherwise it is false. ** ** For ASCII, any character with the high-order bit set is ** allowed in an identifier. For 7-bit characters, ** sqlite3IsIdChar[X] must be 1. ** ** Ticket #1066. the SQL standard does not allow '$' in the ** middle of identifiers. But many SQL implementations do. ** SQLite will allow '$' in identifiers for compatibility. ** But the feature is undocumented. */ static const char isIdChar[] = { /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ |
︙ | ︙ | |||
1708 1709 1710 1711 1712 1713 1714 | /* ** The input azIn is a NULL-terminated list of tokens. Remove the first ** token and all punctuation tokens. Remove the quotes from ** around string literal tokens. ** ** Example: ** | | | | 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 | /* ** The input azIn is a NULL-terminated list of tokens. Remove the first ** token and all punctuation tokens. Remove the quotes from ** around string literal tokens. ** ** Example: ** ** input: tokenize chinese ( 'simplified' , 'mixed' ) ** output: chinese simplified mixed ** ** Another example: ** ** input: delimiters ( '[' , ']' , '...' ) ** output: [ ] ... */ static void tokenListToIdList(char **azIn){ |
︙ | ︙ | |||
2582 2583 2584 2585 2586 2587 2588 | ** is the first term of a phrase query, go ahead and evaluate the phrase ** query and return the doclist for the entire phrase query. ** ** The result is stored in pTerm->doclist. */ static int docListOfTerm( fulltext_vtab *v, /* The full text index */ | | | 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 | ** is the first term of a phrase query, go ahead and evaluate the phrase ** query and return the doclist for the entire phrase query. ** ** The result is stored in pTerm->doclist. */ static int docListOfTerm( fulltext_vtab *v, /* The full text index */ int iColumn, /* column to restrict to. No restriction if >=nColumn */ QueryTerm *pQTerm, /* Term we are looking for, or 1st term of a phrase */ DocList **ppResult /* Write the result here */ ){ DocList *pLeft, *pRight, *pNew; int i, rc; pLeft = docListNew(DL_POSITIONS); |
︙ | ︙ | |||
2656 2657 2658 2659 2660 2661 2662 | } } return -1; } /* ** Parse the text at pSegment[0..nSegment-1]. Add additional terms | | | 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 | } } return -1; } /* ** Parse the text at pSegment[0..nSegment-1]. Add additional terms ** to the query being assembled in pQuery. ** ** inPhrase is true if pSegment[0..nSegement-1] is contained within ** double-quotes. If inPhrase is true, then the first term ** is marked with the number of terms in the phrase less one and ** OR and "-" syntax is ignored. If inPhrase is false, then every ** term found is marked with nPhrase=0 and OR and "-" syntax is significant. */ |
︙ | ︙ | |||
2950 2951 2952 2953 2954 2955 2956 | */ sqlite3_result_blob(pContext, &c, sizeof(c), SQLITE_TRANSIENT); } return SQLITE_OK; } /* This is the xRowid method. The SQLite core calls this routine to | | | 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 | */ sqlite3_result_blob(pContext, &c, sizeof(c), SQLITE_TRANSIENT); } return SQLITE_OK; } /* This is the xRowid method. The SQLite core calls this routine to ** retrieve the rowid for the current row of the result set. The ** rowid should be written to *pRowid. */ static int fulltextRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ fulltext_cursor *c = (fulltext_cursor *) pCursor; *pRowid = sqlite3_column_int64(c->pStmt, 0); return SQLITE_OK; |
︙ | ︙ |
Changes to ext/fts1/fts1_hash.c.
︙ | ︙ | |||
119 120 121 122 123 124 125 | if( n1!=n2 ) return 1; return memcmp(pKey1,pKey2,n1); } /* ** Return a pointer to the appropriate hash function given the key class. ** | | | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | if( n1!=n2 ) return 1; return memcmp(pKey1,pKey2,n1); } /* ** Return a pointer to the appropriate hash function given the key class. ** ** The C syntax in this function definition may be unfamiliar to some ** programmers, so we provide the following additional explanation: ** ** The name of the function is "hashFunction". The function takes a ** single parameter "keyClass". The return value of hashFunction() ** is a pointer to another function. Specifically, the return value ** of hashFunction() is a pointer to a function that takes two parameters ** with types "const void*" and "int" and returns an "int". |
︙ | ︙ | |||
178 179 180 181 182 183 184 | pH->first = pNew; } pEntry->count++; pEntry->chain = pNew; } | | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | pH->first = pNew; } pEntry->count++; pEntry->chain = pNew; } /* Resize the hash table so that it contains "new_size" buckets. ** "new_size" must be a power of 2. The hash table might fail ** to resize if sqliteMalloc() fails. */ static void rehash(fts1Hash *pH, int new_size){ struct _fts1ht *new_ht; /* The new hash table */ fts1HashElem *elem, *next_elem; /* For looping over existing elements */ int (*xHash)(const void*,int); /* The hash function */ |
︙ | ︙ |
Changes to ext/fts1/fts1_porter.c.
︙ | ︙ | |||
139 140 141 142 143 144 145 | ** ** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. ** 'Y' is a consonant unless it follows another consonant, ** in which case it is a vowel. ** ** In these routine, the letters are in reverse order. So the 'y' rule ** is that 'y' is a consonant unless it is followed by another | | | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | ** ** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. ** 'Y' is a consonant unless it follows another consonant, ** in which case it is a vowel. ** ** In these routine, the letters are in reverse order. So the 'y' rule ** is that 'y' is a consonant unless it is followed by another ** consonant. */ static int isVowel(const char*); static int isConsonant(const char *z){ int j; char x = *z; if( x==0 ) return 0; assert( x>='a' && x<='z' ); |
︙ | ︙ | |||
235 236 237 238 239 240 241 | */ static int doubleConsonant(const char *z){ return isConsonant(z) && z[0]==z[1] && isConsonant(z+1); } /* ** Return TRUE if the word ends with three letters which | | | | 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 | */ static int doubleConsonant(const char *z){ return isConsonant(z) && z[0]==z[1] && isConsonant(z+1); } /* ** Return TRUE if the word ends with three letters which ** are consonant-vowel-consonant and where the final consonant ** is not 'w', 'x', or 'y'. ** ** The word is reversed here. So we are really checking the ** first three letters and the first one cannot be in [wxy]. */ static int star_oh(const char *z){ return z[0]!=0 && isConsonant(z) && z[0]!='w' && z[0]!='x' && z[0]!='y' && z[1]!=0 && isVowel(z+1) && z[2]!=0 && isConsonant(z+2); } /* ** If the word ends with zFrom and xCond() is true for the stem ** of the word that precedes the zFrom ending, then change the ** ending to zTo. ** ** The input word *pz and zFrom are both in reverse order. zTo ** is in normal order. ** ** Return TRUE if zFrom matches. Return FALSE if zFrom does not ** match. Not that TRUE is returned even if xCond() fails and |
︙ | ︙ |
Changes to ext/fts2/fts2.c.
︙ | ︙ | |||
101 102 103 104 105 106 107 | ** varint POS_END; (marks end of positions for this document. ** } ** ** Here, array { X } means zero or more occurrences of X, adjacent in ** memory. A "position" is an index of a token in the token stream ** generated by the tokenizer, while an "offset" is a byte offset, ** both based at 0. Note that POS_END and POS_COLUMN occur in the | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | ** varint POS_END; (marks end of positions for this document. ** } ** ** Here, array { X } means zero or more occurrences of X, adjacent in ** memory. A "position" is an index of a token in the token stream ** generated by the tokenizer, while an "offset" is a byte offset, ** both based at 0. Note that POS_END and POS_COLUMN occur in the ** same logical place as the position element, and act as sentinels ** ending a position list array. ** ** A DL_POSITIONS doclist omits the startOffset and endOffset ** information. A DL_DOCIDS doclist omits both the position and ** offset information, becoming an array of varint-encoded docids. ** ** On-disk data is stored as type DL_DEFAULT, so we don't serialize |
︙ | ︙ | |||
2407 2408 2409 2410 2411 2412 2413 | ** IdChar(X) will be true. Otherwise it is false. ** ** For ASCII, any character with the high-order bit set is ** allowed in an identifier. For 7-bit characters, ** sqlite3IsIdChar[X] must be 1. ** ** Ticket #1066. the SQL standard does not allow '$' in the | | | 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 | ** IdChar(X) will be true. Otherwise it is false. ** ** For ASCII, any character with the high-order bit set is ** allowed in an identifier. For 7-bit characters, ** sqlite3IsIdChar[X] must be 1. ** ** Ticket #1066. the SQL standard does not allow '$' in the ** middle of identifiers. But many SQL implementations do. ** SQLite will allow '$' in identifiers for compatibility. ** But the feature is undocumented. */ static const char isIdChar[] = { /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ |
︙ | ︙ | |||
2576 2577 2578 2579 2580 2581 2582 | /* ** The input azIn is a NULL-terminated list of tokens. Remove the first ** token and all punctuation tokens. Remove the quotes from ** around string literal tokens. ** ** Example: ** | | | | 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 | /* ** The input azIn is a NULL-terminated list of tokens. Remove the first ** token and all punctuation tokens. Remove the quotes from ** around string literal tokens. ** ** Example: ** ** input: tokenize chinese ( 'simplified' , 'mixed' ) ** output: chinese simplified mixed ** ** Another example: ** ** input: delimiters ( '[' , ']' , '...' ) ** output: [ ] ... */ static void tokenListToIdList(char **azIn){ |
︙ | ︙ | |||
3519 3520 3521 3522 3523 3524 3525 | } } return -1; } /* ** Parse the text at pSegment[0..nSegment-1]. Add additional terms | | | 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 | } } return -1; } /* ** Parse the text at pSegment[0..nSegment-1]. Add additional terms ** to the query being assembled in pQuery. ** ** inPhrase is true if pSegment[0..nSegement-1] is contained within ** double-quotes. If inPhrase is true, then the first term ** is marked with the number of terms in the phrase less one and ** OR and "-" syntax is ignored. If inPhrase is false, then every ** term found is marked with nPhrase=0 and OR and "-" syntax is significant. */ |
︙ | ︙ | |||
3870 3871 3872 3873 3874 3875 3876 | */ sqlite3_result_blob(pContext, &c, sizeof(c), SQLITE_TRANSIENT); } return SQLITE_OK; } /* This is the xRowid method. The SQLite core calls this routine to | | | 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 | */ sqlite3_result_blob(pContext, &c, sizeof(c), SQLITE_TRANSIENT); } return SQLITE_OK; } /* This is the xRowid method. The SQLite core calls this routine to ** retrieve the rowid for the current row of the result set. The ** rowid should be written to *pRowid. */ static int fulltextRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ fulltext_cursor *c = (fulltext_cursor *) pCursor; *pRowid = sqlite3_column_int64(c->pStmt, 0); return SQLITE_OK; |
︙ | ︙ | |||
4644 4645 4646 4647 4648 4649 4650 | int rc = leafWriterFlush(v, pWriter); if( rc!=SQLITE_OK ) return rc; } /* We must have flushed a leaf at some point. */ assert( pWriter->has_parent ); | | | 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 | int rc = leafWriterFlush(v, pWriter); if( rc!=SQLITE_OK ) return rc; } /* We must have flushed a leaf at some point. */ assert( pWriter->has_parent ); /* Tentatively set the end leaf blockid as the end blockid. If the ** interior node can be returned inline, this will be the final ** blockid, otherwise it will be overwritten by ** interiorWriterRootInfo(). */ *piEndBlockid = pWriter->iEndBlockid; return interiorWriterRootInfo(v, &pWriter->parentWriter, |
︙ | ︙ | |||
6014 6015 6016 6017 6018 6019 6020 | /* OptLeavesReader is nearly identical to LeavesReader, except that ** where LeavesReader is geared towards the merging of complete ** segment levels (with exactly MERGE_COUNT segments), OptLeavesReader ** is geared towards implementation of the optimize() function, and ** can merge all segments simultaneously. This version may be ** somewhat less efficient than LeavesReader because it merges into an ** accumulator rather than doing an N-way merge, but since segment | | | 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 | /* OptLeavesReader is nearly identical to LeavesReader, except that ** where LeavesReader is geared towards the merging of complete ** segment levels (with exactly MERGE_COUNT segments), OptLeavesReader ** is geared towards implementation of the optimize() function, and ** can merge all segments simultaneously. This version may be ** somewhat less efficient than LeavesReader because it merges into an ** accumulator rather than doing an N-way merge, but since segment ** size grows exponentially (so segment count logarithmically) this is ** probably not an immediate problem. */ /* TODO(shess): Prove that assertion, or extend the merge code to ** merge tree fashion (like the prefix-searching code does). */ /* TODO(shess): OptLeavesReader and LeavesReader could probably be ** merged with little or no loss of performance for LeavesReader. The |
︙ | ︙ |
Changes to ext/fts2/fts2_hash.c.
︙ | ︙ | |||
126 127 128 129 130 131 132 | if( n1!=n2 ) return 1; return memcmp(pKey1,pKey2,n1); } /* ** Return a pointer to the appropriate hash function given the key class. ** | | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | if( n1!=n2 ) return 1; return memcmp(pKey1,pKey2,n1); } /* ** Return a pointer to the appropriate hash function given the key class. ** ** The C syntax in this function definition may be unfamiliar to some ** programmers, so we provide the following additional explanation: ** ** The name of the function is "hashFunction". The function takes a ** single parameter "keyClass". The return value of hashFunction() ** is a pointer to another function. Specifically, the return value ** of hashFunction() is a pointer to a function that takes two parameters ** with types "const void*" and "int" and returns an "int". |
︙ | ︙ | |||
185 186 187 188 189 190 191 | pH->first = pNew; } pEntry->count++; pEntry->chain = pNew; } | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | pH->first = pNew; } pEntry->count++; pEntry->chain = pNew; } /* Resize the hash table so that it contains "new_size" buckets. ** "new_size" must be a power of 2. The hash table might fail ** to resize if sqliteMalloc() fails. */ static void rehash(fts2Hash *pH, int new_size){ struct _fts2ht *new_ht; /* The new hash table */ fts2HashElem *elem, *next_elem; /* For looping over existing elements */ int (*xHash)(const void*,int); /* The hash function */ |
︙ | ︙ |
Changes to ext/fts2/fts2_porter.c.
︙ | ︙ | |||
141 142 143 144 145 146 147 | ** ** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. ** 'Y' is a consonant unless it follows another consonant, ** in which case it is a vowel. ** ** In these routine, the letters are in reverse order. So the 'y' rule ** is that 'y' is a consonant unless it is followed by another | | | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | ** ** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. ** 'Y' is a consonant unless it follows another consonant, ** in which case it is a vowel. ** ** In these routine, the letters are in reverse order. So the 'y' rule ** is that 'y' is a consonant unless it is followed by another ** consonant. */ static int isVowel(const char*); static int isConsonant(const char *z){ int j; char x = *z; if( x==0 ) return 0; assert( x>='a' && x<='z' ); |
︙ | ︙ | |||
237 238 239 240 241 242 243 | */ static int doubleConsonant(const char *z){ return isConsonant(z) && z[0]==z[1] && isConsonant(z+1); } /* ** Return TRUE if the word ends with three letters which | | | | 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 | */ static int doubleConsonant(const char *z){ return isConsonant(z) && z[0]==z[1] && isConsonant(z+1); } /* ** Return TRUE if the word ends with three letters which ** are consonant-vowel-consonant and where the final consonant ** is not 'w', 'x', or 'y'. ** ** The word is reversed here. So we are really checking the ** first three letters and the first one cannot be in [wxy]. */ static int star_oh(const char *z){ return z[0]!=0 && isConsonant(z) && z[0]!='w' && z[0]!='x' && z[0]!='y' && z[1]!=0 && isVowel(z+1) && z[2]!=0 && isConsonant(z+2); } /* ** If the word ends with zFrom and xCond() is true for the stem ** of the word that precedes the zFrom ending, then change the ** ending to zTo. ** ** The input word *pz and zFrom are both in reverse order. zTo ** is in normal order. ** ** Return TRUE if zFrom matches. Return FALSE if zFrom does not ** match. Not that TRUE is returned even if xCond() fails and |
︙ | ︙ |
Changes to ext/fts2/mkfts2amal.tcl.
︙ | ︙ | |||
61 62 63 64 65 66 67 | set nstar [expr {60 - $n}] set stars [string range $s78 0 $nstar] puts $out "/************** $text $stars/" } # Read the source file named $filename and write it into the # sqlite3.c output file. If any #include statements are seen, | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | set nstar [expr {60 - $n}] set stars [string range $s78 0 $nstar] puts $out "/************** $text $stars/" } # Read the source file named $filename and write it into the # sqlite3.c output file. If any #include statements are seen, # process them appropriately. # proc copy_file {filename} { global seen_hdr available_hdr out set tail [file tail $filename] section_comment "Begin file $tail" set in [open $filename r] while {![eof $in]} { |
︙ | ︙ |
Changes to ext/fts3/README.syntax.
︙ | ︙ | |||
12 13 14 15 16 17 18 | (in this case "t1"), or by the name of one of the columns of the fts3 table. <full-text-query> should be replaced by an SQL expression that computes to a string containing an Fts3 query. If the left-hand-side of the MATCH operator is set to the name of the fts3 table, then by default the query may be matched against any column of the table. If it is set to a column name, then by default the query | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | (in this case "t1"), or by the name of one of the columns of the fts3 table. <full-text-query> should be replaced by an SQL expression that computes to a string containing an Fts3 query. If the left-hand-side of the MATCH operator is set to the name of the fts3 table, then by default the query may be matched against any column of the table. If it is set to a column name, then by default the query may only match the specified column. In both cases this may be overridden as part of the query text (see sections 2 and 3 below). As of SQLite version 3.6.8, Fts3 supports two slightly different query formats; the standard syntax, which is used by default, and the enhanced query syntax which can be selected by compiling with the pre-processor symbol SQLITE_ENABLE_FTS3_PARENTHESIS defined. |
︙ | ︙ | |||
58 59 60 61 62 63 64 | case is treated as an ordinary token. For example, the following query: <col> MATCH 'engineering NEAR consultancy' matches rows that contain both the "engineering" and "consultancy" tokens in the same column with not more than 10 other words between them. It does not matter which of the two terms occurs first in the document, only that | | | | | 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 | case is treated as an ordinary token. For example, the following query: <col> MATCH 'engineering NEAR consultancy' matches rows that contain both the "engineering" and "consultancy" tokens in the same column with not more than 10 other words between them. It does not matter which of the two terms occurs first in the document, only that they be separated by only 10 tokens or less. The user may also specify a different required proximity by adding "/N" immediately after the NEAR operator, where N is an integer. For example: <col> MATCH 'engineering NEAR/5 consultancy' searches for a row containing an instance of each specified token separated by not more than 5 other tokens. More than one NEAR operator can be used in as sequence. For example this query: <col> MATCH 'reliable NEAR/2 engineering NEAR/5 consultancy' searches for a row that contains an instance of the token "reliable" separated by not more than two tokens from an instance of "engineering", which is in turn separated by not more than 5 other tokens from an instance of the term "consultancy". Phrases enclosed in quotes may also be used as arguments to the NEAR operator. Similar to the NEAR operator, one or more tokens or phrases may be separated by OR operators. In this case, only one of the specified tokens or phrases must appear in the document. For example, the query: |
︙ | ︙ | |||
142 143 144 145 146 147 148 | 1) Parenthesis are supported. When using the enhanced query syntax, parenthesis may be used to overcome the built-in precedence of the supplied binary operators. For example, the following query: <col> MATCH '(hello world) OR (simple example)' matches documents that contain both "hello" and "world", and documents | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | 1) Parenthesis are supported. When using the enhanced query syntax, parenthesis may be used to overcome the built-in precedence of the supplied binary operators. For example, the following query: <col> MATCH '(hello world) OR (simple example)' matches documents that contain both "hello" and "world", and documents that contain both "simple" and "example". It is not possible to formulate such a query using the standard syntax. 2) Instead of separating tokens and phrases by whitespace, an AND operator may be explicitly specified. This does not change query processing at all, but may be used to improve readability. For example, the following query is handled identically to the one above: |
︙ | ︙ | |||
170 171 172 173 174 175 176 | <col> MATCH 'example NOT simple' As for all other operators, the NOT operator must be specified in upper case. Otherwise it will be treated as a regular token. 4) Unlike in the standard syntax, where the OR operator has a higher precedence than the implicit AND operator, when using the enhanced | | | 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | <col> MATCH 'example NOT simple' As for all other operators, the NOT operator must be specified in upper case. Otherwise it will be treated as a regular token. 4) Unlike in the standard syntax, where the OR operator has a higher precedence than the implicit AND operator, when using the enhanced syntax implicit and explicit AND operators have a higher precedence than OR operators. Using the enhanced syntax, the following two queries are equivalent: <col> MATCH 'sqlite fantastic OR impressive' <col> MATCH '(sqlite AND fantastic) OR impressive' however, when using the standard syntax, the query: |
︙ | ︙ |
Changes to ext/fts3/fts3.c.
︙ | ︙ | |||
83 84 85 86 87 88 89 | ** } ** varint POS_END; (marks end of positions for this document. ** } ** ** Here, array { X } means zero or more occurrences of X, adjacent in ** memory. A "position" is an index of a token in the token stream ** generated by the tokenizer. Note that POS_END and POS_COLUMN occur | | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | ** } ** varint POS_END; (marks end of positions for this document. ** } ** ** Here, array { X } means zero or more occurrences of X, adjacent in ** memory. A "position" is an index of a token in the token stream ** generated by the tokenizer. Note that POS_END and POS_COLUMN occur ** in the same logical place as the position element, and act as sentinels ** ending a position list array. POS_END is 0. POS_COLUMN is 1. ** The positions numbers are not stored literally but rather as two more ** than the difference from the prior position, or the just the position plus ** 2 for the first position. Example: ** ** label: A B C D E F G H I J K ** value: 123 5 9 1 1 14 35 0 234 72 0 |
︙ | ︙ | |||
2628 2629 2630 2631 2632 2633 2634 | ** be larger in the output than it was in the input (since the delta value ** may be a larger positive integer than the actual docid). ** ** The space required to store the output is therefore the sum of the ** sizes of the two inputs, plus enough space for exactly one of the input ** docids to grow. ** | | | 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 | ** be larger in the output than it was in the input (since the delta value ** may be a larger positive integer than the actual docid). ** ** The space required to store the output is therefore the sum of the ** sizes of the two inputs, plus enough space for exactly one of the input ** docids to grow. ** ** A symmetric argument may be made if the doclists are in descending ** order. */ aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING); if( !aOut ) return SQLITE_NOMEM; p = aOut; fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); |
︙ | ︙ | |||
4650 4651 4652 4653 4654 4655 4656 | /* ** The phrase iterator passed as the second argument: ** ** * features at least one token that uses an incremental doclist, and ** ** * does not contain any deferred tokens. ** | | | 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 | /* ** The phrase iterator passed as the second argument: ** ** * features at least one token that uses an incremental doclist, and ** ** * does not contain any deferred tokens. ** ** Advance it to the next matching document in the database and populate ** the Fts3Doclist.pList and nList fields. ** ** If there is no "next" entry and no error occurs, then *pbEof is set to ** 1 before returning. Otherwise, if no error occurs and the iterator is ** successfully advanced, *pbEof is set to 0. ** ** If an error occurs, return an SQLite error code. Otherwise, return |
︙ | ︙ | |||
5660 5661 5662 5663 5664 5665 5666 | pCsr->isEof = 1; } return rc; } /* | | | 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 | pCsr->isEof = 1; } return rc; } /* ** Restart iteration for expression pExpr so that the next call to ** fts3EvalNext() visits the first row. Do not allow incremental ** loading or merging of phrase doclists for this iteration. ** ** If *pRc is other than SQLITE_OK when this function is called, it is ** a no-op. If an error occurs within this function, *pRc is set to an ** SQLite error code before returning. */ |
︙ | ︙ |
Changes to ext/fts3/fts3Int.h.
︙ | ︙ | |||
23 24 25 26 27 28 29 | # undef SQLITE_ENABLE_FTS3 # undef SQLITE_ENABLE_FTS4 #endif /* ** FTS4 is really an extension for FTS3. It is enabled using the ** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | # undef SQLITE_ENABLE_FTS3 # undef SQLITE_ENABLE_FTS4 #endif /* ** FTS4 is really an extension for FTS3. It is enabled using the ** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all ** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3. */ #if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) # define SQLITE_ENABLE_FTS3 #endif #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
︙ | ︙ | |||
128 129 130 131 132 133 134 | */ #define POS_COLUMN (1) /* Column-list terminator */ #define POS_END (0) /* Position-list terminator */ /* ** The assert_fts3_nc() macro is similar to the assert() macro, except that it ** is used for assert() conditions that are true only if it can be | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | */ #define POS_COLUMN (1) /* Column-list terminator */ #define POS_END (0) /* Position-list terminator */ /* ** The assert_fts3_nc() macro is similar to the assert() macro, except that it ** is used for assert() conditions that are true only if it can be ** guaranteed that the database is not corrupt. */ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) extern int sqlite3_fts3_may_be_corrupt; # define assert_fts3_nc(x) assert(sqlite3_fts3_may_be_corrupt || (x)) #else # define assert_fts3_nc(x) assert(x) #endif |
︙ | ︙ | |||
350 351 352 353 354 355 356 | #define FTS3_EVAL_FILTER 0 #define FTS3_EVAL_NEXT 1 #define FTS3_EVAL_MATCHINFO 2 /* ** The Fts3Cursor.eSearch member is always set to one of the following. | | | 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 | #define FTS3_EVAL_FILTER 0 #define FTS3_EVAL_NEXT 1 #define FTS3_EVAL_MATCHINFO 2 /* ** The Fts3Cursor.eSearch member is always set to one of the following. ** Actually, Fts3Cursor.eSearch can be greater than or equal to ** FTS3_FULLTEXT_SEARCH. If so, then Fts3Cursor.eSearch - 2 is the index ** of the column to be searched. For example, in ** ** CREATE VIRTUAL TABLE ex1 USING fts3(a,b,c,d); ** SELECT docid FROM ex1 WHERE b MATCH 'one two three'; ** ** Because the LHS of the MATCH operator is 2nd column "b", |
︙ | ︙ |
Changes to ext/fts3/fts3_expr.c.
︙ | ︙ | |||
649 650 651 652 653 654 655 | p = pPrev; }else{ int eType = p->eType; isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); /* The isRequirePhrase variable is set to true if a phrase or ** an expression contained in parenthesis is required. If a | | | 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 | p = pPrev; }else{ int eType = p->eType; isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); /* The isRequirePhrase variable is set to true if a phrase or ** an expression contained in parenthesis is required. If a ** binary operator (AND, OR, NOT or NEAR) is encountered when ** isRequirePhrase is set, this is a syntax error. */ if( !isPhrase && isRequirePhrase ){ sqlite3Fts3ExprFree(p); rc = SQLITE_ERROR; goto exprparse_out; } |
︙ | ︙ |
Changes to ext/fts3/fts3_hash.c.
︙ | ︙ | |||
124 125 126 127 128 129 130 | if( n1!=n2 ) return 1; return memcmp(pKey1,pKey2,n1); } /* ** Return a pointer to the appropriate hash function given the key class. ** | | | 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | if( n1!=n2 ) return 1; return memcmp(pKey1,pKey2,n1); } /* ** Return a pointer to the appropriate hash function given the key class. ** ** The C syntax in this function definition may be unfamiliar to some ** programmers, so we provide the following additional explanation: ** ** The name of the function is "ftsHashFunction". The function takes a ** single parameter "keyClass". The return value of ftsHashFunction() ** is a pointer to another function. Specifically, the return value ** of ftsHashFunction() is a pointer to a function that takes two parameters ** with types "const void*" and "int" and returns an "int". |
︙ | ︙ | |||
183 184 185 186 187 188 189 | pH->first = pNew; } pEntry->count++; pEntry->chain = pNew; } | | | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | pH->first = pNew; } pEntry->count++; pEntry->chain = pNew; } /* Resize the hash table so that it contains "new_size" buckets. ** "new_size" must be a power of 2. The hash table might fail ** to resize if sqliteMalloc() fails. ** ** Return non-zero if a memory allocation error occurs. */ static int fts3Rehash(Fts3Hash *pH, int new_size){ struct _fts3ht *new_ht; /* The new hash table */ |
︙ | ︙ |
Changes to ext/fts3/fts3_porter.c.
︙ | ︙ | |||
140 141 142 143 144 145 146 | ** ** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. ** 'Y' is a consonant unless it follows another consonant, ** in which case it is a vowel. ** ** In these routine, the letters are in reverse order. So the 'y' rule ** is that 'y' is a consonant unless it is followed by another | | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | ** ** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. ** 'Y' is a consonant unless it follows another consonant, ** in which case it is a vowel. ** ** In these routine, the letters are in reverse order. So the 'y' rule ** is that 'y' is a consonant unless it is followed by another ** consonant. */ static int isVowel(const char*); static int isConsonant(const char *z){ int j; char x = *z; if( x==0 ) return 0; assert( x>='a' && x<='z' ); |
︙ | ︙ | |||
236 237 238 239 240 241 242 | */ static int doubleConsonant(const char *z){ return isConsonant(z) && z[0]==z[1]; } /* ** Return TRUE if the word ends with three letters which | | | | 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 | */ static int doubleConsonant(const char *z){ return isConsonant(z) && z[0]==z[1]; } /* ** Return TRUE if the word ends with three letters which ** are consonant-vowel-consonant and where the final consonant ** is not 'w', 'x', or 'y'. ** ** The word is reversed here. So we are really checking the ** first three letters and the first one cannot be in [wxy]. */ static int star_oh(const char *z){ return isConsonant(z) && z[0]!='w' && z[0]!='x' && z[0]!='y' && isVowel(z+1) && isConsonant(z+2); } /* ** If the word ends with zFrom and xCond() is true for the stem ** of the word that precedes the zFrom ending, then change the ** ending to zTo. ** ** The input word *pz and zFrom are both in reverse order. zTo ** is in normal order. ** ** Return TRUE if zFrom matches. Return FALSE if zFrom does not ** match. Not that TRUE is returned even if xCond() fails and |
︙ | ︙ |
Changes to ext/fts3/fts3_snippet.c.
︙ | ︙ | |||
602 603 604 605 606 607 608 | int nAppend /* Size of zAppend in bytes (or -1) */ ){ if( nAppend<0 ){ nAppend = (int)strlen(zAppend); } /* If there is insufficient space allocated at StrBuffer.z, use realloc() | | | 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 | int nAppend /* Size of zAppend in bytes (or -1) */ ){ if( nAppend<0 ){ nAppend = (int)strlen(zAppend); } /* If there is insufficient space allocated at StrBuffer.z, use realloc() ** to grow the buffer until so that it is big enough to accommodate the ** appended data. */ if( pStr->n+nAppend+1>=pStr->nAlloc ){ sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100; char *zNew = sqlite3_realloc64(pStr->z, nAlloc); if( !zNew ){ return SQLITE_NOMEM; |
︙ | ︙ |
Changes to ext/fts3/fts3_unicode2.c.
︙ | ︙ | |||
152 153 154 155 156 157 158 | /* ** If the argument is a codepoint corresponding to a lowercase letter ** in the ASCII range with a diacritic added, return the codepoint ** of the ASCII letter only. For example, if passed 235 - "LATIN ** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER | | | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | /* ** If the argument is a codepoint corresponding to a lowercase letter ** in the ASCII range with a diacritic added, return the codepoint ** of the ASCII letter only. For example, if passed 235 - "LATIN ** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER ** E"). The results of passing a codepoint that corresponds to an ** uppercase letter are undefined. */ static int remove_diacritic(int c, int bComplex){ unsigned short aDia[] = { 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, |
︙ | ︙ |
Changes to ext/fts3/fts3_write.c.
︙ | ︙ | |||
3935 3936 3937 3938 3939 3940 3941 | ** If the size of the value in blob pPrev is zero, then this is the first ** term written to the node. Otherwise, pPrev contains a copy of the ** previous term. Before this function returns, it is updated to contain a ** copy of zTerm/nTerm. ** ** It is assumed that the buffer associated with pNode is already large ** enough to accommodate the new entry. The buffer associated with pPrev | | | 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 | ** If the size of the value in blob pPrev is zero, then this is the first ** term written to the node. Otherwise, pPrev contains a copy of the ** previous term. Before this function returns, it is updated to contain a ** copy of zTerm/nTerm. ** ** It is assumed that the buffer associated with pNode is already large ** enough to accommodate the new entry. The buffer associated with pPrev ** is extended by this function if required. ** ** If an error (i.e. OOM condition) occurs, an SQLite error code is ** returned. Otherwise, SQLITE_OK. */ static int fts3AppendToNode( Blob *pNode, /* Current node image to append to */ Blob *pPrev, /* Buffer containing previous term written */ |
︙ | ︙ | |||
4715 4716 4717 4718 4719 4720 4721 | sqlite3_free(root.a); sqlite3_free(block.a); return rc; } /* | | | 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 | sqlite3_free(root.a); sqlite3_free(block.a); return rc; } /* ** This function is called after an incremental-merge operation has run to ** merge (or partially merge) two or more segments from absolute level ** iAbsLevel. ** ** Each input segment is either removed from the db completely (if all of ** its data was copied to the output segment by the incrmerge operation) ** or modified in place so that it no longer contains those entries that ** have been duplicated in the output segment. |
︙ | ︙ | |||
5444 5445 5446 5447 5448 5449 5450 | for(pDef=pCsr->pDeferred; pDef; pDef=pDef->pNext){ fts3PendingListDelete(pDef->pList); pDef->pList = 0; } } /* | | | 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 | for(pDef=pCsr->pDeferred; pDef; pDef=pDef->pNext){ fts3PendingListDelete(pDef->pList); pDef->pList = 0; } } /* ** Free all entries in the pCsr->pDeferred list. Entries are added to ** this list using sqlite3Fts3DeferToken(). */ void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *pCsr){ Fts3DeferredToken *pDef; Fts3DeferredToken *pNext; for(pDef=pCsr->pDeferred; pDef; pDef=pNext){ pNext = pDef->pNext; |
︙ | ︙ | |||
5575 5576 5577 5578 5579 5580 5581 | return SQLITE_OK; } #endif /* ** SQLite value pRowid contains the rowid of a row that may or may not be ** present in the FTS3 table. If it is, delete it and adjust the contents | | | 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 | return SQLITE_OK; } #endif /* ** SQLite value pRowid contains the rowid of a row that may or may not be ** present in the FTS3 table. If it is, delete it and adjust the contents ** of subsidiary data structures accordingly. */ static int fts3DeleteByRowid( Fts3Table *p, sqlite3_value *pRowid, int *pnChng, /* IN/OUT: Decrement if row is deleted */ u32 *aSzDel ){ |
︙ | ︙ |
Changes to ext/fts3/fts3speed.tcl.
︙ | ︙ | |||
115 116 117 118 119 120 121 | close $::fd puts "Success. Created files:" puts " fts3speed_insert.sql" puts " fts3speed_select.sql" puts " fts3speed_select2.sql" puts " fts3speed_optimize.sql" | < | 115 116 117 118 119 120 121 | close $::fd puts "Success. Created files:" puts " fts3speed_insert.sql" puts " fts3speed_select.sql" puts " fts3speed_select2.sql" puts " fts3speed_optimize.sql" |
Changes to ext/fts3/mkfts3amal.tcl.
︙ | ︙ | |||
61 62 63 64 65 66 67 | set nstar [expr {60 - $n}] set stars [string range $s78 0 $nstar] puts $out "/************** $text $stars/" } # Read the source file named $filename and write it into the # sqlite3.c output file. If any #include statements are seen, | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | set nstar [expr {60 - $n}] set stars [string range $s78 0 $nstar] puts $out "/************** $text $stars/" } # Read the source file named $filename and write it into the # sqlite3.c output file. If any #include statements are seen, # process them appropriately. # proc copy_file {filename} { global seen_hdr available_hdr out set tail [file tail $filename] section_comment "Begin file $tail" set in [open $filename r] while {![eof $in]} { |
︙ | ︙ |
Changes to ext/fts3/tool/fts3cov.sh.
︙ | ︙ | |||
9 10 11 12 13 14 15 | for f in `ls $srcdir/ext/fts3/*.c` do f=`basename $f` echo -ne "$f: " gcov -b $f | grep Taken | sed 's/Taken at least once://' done | < | 9 10 11 12 13 14 15 | for f in `ls $srcdir/ext/fts3/*.c` do f=`basename $f` echo -ne "$f: " gcov -b $f | grep Taken | sed 's/Taken at least once://' done |
Changes to ext/fts3/unicode/mkunicode.tcl.
︙ | ︙ | |||
42 43 44 45 46 47 48 | lappend aFlag $fPrev puts "/*" puts "** If the argument is a codepoint corresponding to a lowercase letter" puts "** in the ASCII range with a diacritic added, return the codepoint" puts "** of the ASCII letter only. For example, if passed 235 - \"LATIN" puts "** SMALL LETTER E WITH DIAERESIS\" - return 65 (\"LATIN SMALL LETTER" | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | lappend aFlag $fPrev puts "/*" puts "** If the argument is a codepoint corresponding to a lowercase letter" puts "** in the ASCII range with a diacritic added, return the codepoint" puts "** of the ASCII letter only. For example, if passed 235 - \"LATIN" puts "** SMALL LETTER E WITH DIAERESIS\" - return 65 (\"LATIN SMALL LETTER" puts "** E\"). The results of passing a codepoint that corresponds to an" puts "** uppercase letter are undefined." puts "*/" puts "static int ${::remove_diacritic}(int c, int bComplex)\{" puts " unsigned short aDia\[\] = \{" puts -nonewline " 0, " set i 1 foreach r $lRange { |
︙ | ︙ | |||
885 886 887 888 889 890 891 | puts " if( r3 ) printf(\"categories(): Problem with code %d\\n\",code);" puts " else printf(\"categories(): test passed\\n\");" } puts " return (r1 || r2 || r3);" puts "\}" } | | | 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 | puts " if( r3 ) printf(\"categories(): Problem with code %d\\n\",code);" puts " else printf(\"categories(): test passed\\n\");" } puts " return (r1 || r2 || r3);" puts "\}" } # Process the command line arguments. Exit early if they are not to # our liking. # proc usage {} { puts -nonewline stderr "Usage: $::argv0 ?-test? ?-fts5? " puts stderr "<CaseFolding.txt file> <UnicodeData.txt file>" exit 1 } |
︙ | ︙ |
Changes to ext/fts3/unicode/parseunicode.tcl.
︙ | ︙ | |||
66 67 68 69 70 71 72 | set iDia [expr "0x[lindex $character_decomposition_mapping 1]"] # Filter out upper-case characters, as they will be mapped to their # lower-case equivalents before this data is used. if {[info exists tl_lookup_table($iCode)]} continue # Check if this is an indirect mapping. If so, set bIndirect to true | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | set iDia [expr "0x[lindex $character_decomposition_mapping 1]"] # Filter out upper-case characters, as they will be mapped to their # lower-case equivalents before this data is used. if {[info exists tl_lookup_table($iCode)]} continue # Check if this is an indirect mapping. If so, set bIndirect to true # and change $iAscii to the indirectly mapped ASCII character. set bIndirect 0 if {[info exists dia($iDia)] && [info exists mapping($iAscii)]} { set iAscii $mapping($iAscii) set bIndirect 1 } if { ($iAscii >= 97 && $iAscii <= 122) |
︙ | ︙ | |||
197 198 199 200 201 202 203 | lappend lRet [list $code $general_category] } close $fd set lRet } | < < | 197 198 199 200 201 202 203 | lappend lRet [list $code $general_category] } close $fd set lRet } |
Changes to ext/fts5/extract_api_docs.tcl.
︙ | ︙ | |||
241 242 243 244 245 246 247 | default { } } } main $data set ::fts5_docs_output | < < < < < | 241 242 243 244 245 246 247 | default { } } } main $data set ::fts5_docs_output |
Changes to ext/fts5/fts5Int.h.
︙ | ︙ | |||
79 80 81 82 83 84 85 | #else # define FTS5_CORRUPT SQLITE_CORRUPT_VTAB #endif /* ** The assert_nc() macro is similar to the assert() macro, except that it ** is used for assert() conditions that are true only if it can be | | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | #else # define FTS5_CORRUPT SQLITE_CORRUPT_VTAB #endif /* ** The assert_nc() macro is similar to the assert() macro, except that it ** is used for assert() conditions that are true only if it can be ** guaranteed that the database is not corrupt. */ #ifdef SQLITE_DEBUG extern int sqlite3_fts5_may_be_corrupt; # define assert_nc(x) assert(sqlite3_fts5_may_be_corrupt || (x)) #else # define assert_nc(x) assert(x) #endif |
︙ | ︙ |
Changes to ext/fts5/fts5_aux.c.
︙ | ︙ | |||
604 605 606 607 608 609 610 | ** IDF = log( (N - nHit + 0.5) / (nHit + 0.5) ) ** ** where "N" is the total number of documents in the set and nHit ** is the number that contain at least one instance of the phrase ** under consideration. ** ** The problem with this is that if (N < 2*nHit), the IDF is | | | 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 | ** IDF = log( (N - nHit + 0.5) / (nHit + 0.5) ) ** ** where "N" is the total number of documents in the set and nHit ** is the number that contain at least one instance of the phrase ** under consideration. ** ** The problem with this is that if (N < 2*nHit), the IDF is ** negative. Which is undesirable. So the minimum allowable IDF is ** (1e-6) - roughly the same as a term that appears in just over ** half of set of 5,000,000 documents. */ double idf = log( (nRow - nHit + 0.5) / (nHit + 0.5) ); if( idf<=0.0 ) idf = 1e-6; p->aIDF[i] = idf; } } |
︙ | ︙ |
Changes to ext/fts5/fts5_buffer.c.
︙ | ︙ | |||
296 297 298 299 300 301 302 | ** Return true if character 't' may be part of an FTS5 bareword, or false ** otherwise. Characters that may be part of barewords: ** ** * All non-ASCII characters, ** * The 52 upper and lower case ASCII characters, and ** * The 10 integer ASCII characters. ** * The underscore character "_" (0x5F). | | | 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | ** Return true if character 't' may be part of an FTS5 bareword, or false ** otherwise. Characters that may be part of barewords: ** ** * All non-ASCII characters, ** * The 52 upper and lower case ASCII characters, and ** * The 10 integer ASCII characters. ** * The underscore character "_" (0x5F). ** * The unicode "substitute" character (0x1A). */ int sqlite3Fts5IsBareword(char t){ u8 aBareword[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 .. 0x0F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* 0x10 .. 0x1F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 .. 0x2F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30 .. 0x3F */ |
︙ | ︙ |
Changes to ext/fts5/fts5_expr.c.
︙ | ︙ | |||
2005 2006 2007 2008 2009 2010 2011 | } } pColset->nCol = iOut; } /* ** Recursively apply colset pColset to expression node pNode and all of | | | 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 | } } pColset->nCol = iOut; } /* ** Recursively apply colset pColset to expression node pNode and all of ** its descendents. If (*ppFree) is not NULL, it contains a spare copy ** of pColset. This function may use the spare copy and set (*ppFree) to ** zero, or it may create copies of pColset using fts5CloneColset(). */ static void fts5ParseSetColset( Fts5Parse *pParse, Fts5ExprNode *pNode, Fts5Colset *pColset, |
︙ | ︙ |
Changes to ext/fts5/fts5_hash.c.
︙ | ︙ | |||
16 17 18 19 20 21 22 | #include "fts5Int.h" typedef struct Fts5HashEntry Fts5HashEntry; /* ** This file contains the implementation of an in-memory hash table used | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include "fts5Int.h" typedef struct Fts5HashEntry Fts5HashEntry; /* ** This file contains the implementation of an in-memory hash table used ** to accumulate "term -> doclist" content before it is flused to a level-0 ** segment. */ struct Fts5Hash { int eDetail; /* Copy of Fts5Config.eDetail */ int *pnByte; /* Pointer to bytes counter */ |
︙ | ︙ | |||
68 69 70 71 72 73 74 | u8 bContent; /* Set content-flag (detail=none mode) */ i16 iCol; /* Column of last value written */ int iPos; /* Position of last value written */ i64 iRowid; /* Rowid of last value written */ }; /* | | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | u8 bContent; /* Set content-flag (detail=none mode) */ i16 iCol; /* Column of last value written */ int iPos; /* Position of last value written */ i64 iRowid; /* Rowid of last value written */ }; /* ** Equivalent to: ** ** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; } */ #define fts5EntryKey(p) ( ((char *)(&(p)[1])) ) /* |
︙ | ︙ |
Changes to ext/fts5/fts5_index.c.
︙ | ︙ | |||
4134 4135 4136 4137 4138 4139 4140 | Fts5Buffer buf; memset(&buf, 0, sizeof(Fts5Buffer)); for(i=0; i<pIter->nSeg && p->rc==SQLITE_OK; i++){ Fts5SegIter *pSeg = &pIter->aSeg[i]; if( pSeg->pSeg==0 ){ /* no-op */ }else if( pSeg->pLeaf==0 ){ | | | 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 | Fts5Buffer buf; memset(&buf, 0, sizeof(Fts5Buffer)); for(i=0; i<pIter->nSeg && p->rc==SQLITE_OK; i++){ Fts5SegIter *pSeg = &pIter->aSeg[i]; if( pSeg->pSeg==0 ){ /* no-op */ }else if( pSeg->pLeaf==0 ){ /* All keys from this input segment have been transferred to the output. ** Set both the first and last page-numbers to 0 to indicate that the ** segment is now empty. */ pSeg->pSeg->pgnoLast = 0; pSeg->pSeg->pgnoFirst = 0; }else{ int iOff = pSeg->iTermLeafOffset; /* Offset on new first leaf page */ i64 iLeafRowid; |
︙ | ︙ | |||
4205 4206 4207 4208 4209 4210 4211 | } /* ** */ static void fts5IndexMergeLevel( Fts5Index *p, /* FTS5 backend object */ | | | 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 | } /* ** */ static void fts5IndexMergeLevel( Fts5Index *p, /* FTS5 backend object */ Fts5Structure **ppStruct, /* IN/OUT: Structure of index */ int iLvl, /* Level to read input from */ int *pnRem /* Write up to this many output leaves */ ){ Fts5Structure *pStruct = *ppStruct; Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl]; Fts5StructureLevel *pLvlOut; Fts5Iter *pIter = 0; /* Iterator to read input data */ |
︙ | ︙ | |||
6166 6167 6168 6169 6170 6171 6172 | *pbDlidx = (int)(iRowid & 0x0001); iRowid >>= FTS5_DATA_DLI_B; *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1)); } static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ | | | 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 | *pbDlidx = (int)(iRowid & 0x0001); iRowid >>= FTS5_DATA_DLI_B; *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1)); } static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ int iSegid, iHeight, iPgno, bDlidx; /* Rowid components */ fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno); if( iSegid==0 ){ if( iKey==FTS5_AVERAGES_ROWID ){ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} "); }else{ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}"); |
︙ | ︙ |
Changes to ext/fts5/fts5_main.c.
︙ | ︙ | |||
1627 1628 1629 1630 1631 1632 1633 | eConflict = sqlite3_vtab_on_conflict(pConfig->db); } assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL ); assert( nArg!=1 || eType0==SQLITE_INTEGER ); /* Filter out attempts to run UPDATE or DELETE on contentless tables. | | | 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 | eConflict = sqlite3_vtab_on_conflict(pConfig->db); } assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL ); assert( nArg!=1 || eType0==SQLITE_INTEGER ); /* Filter out attempts to run UPDATE or DELETE on contentless tables. ** This is not supported. */ if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){ pTab->p.base.zErrMsg = sqlite3_mprintf( "cannot %s contentless fts5 table: %s", (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName ); rc = SQLITE_ERROR; } |
︙ | ︙ |
Changes to ext/fts5/fts5_test_mi.c.
︙ | ︙ | |||
383 384 385 386 387 388 389 | if( rc==SQLITE_OK ){ rc = fts5MatchinfoIter(pApi, pFts, p, fts5MatchinfoLocalCb); } if( rc!=SQLITE_OK ){ sqlite3_result_error_code(pCtx, rc); }else{ | | | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | if( rc==SQLITE_OK ){ rc = fts5MatchinfoIter(pApi, pFts, p, fts5MatchinfoLocalCb); } if( rc!=SQLITE_OK ){ sqlite3_result_error_code(pCtx, rc); }else{ /* No errors has occurred, so return a copy of the array of integers. */ int nByte = p->nRet * sizeof(u32); sqlite3_result_blob(pCtx, (void*)p->aRet, nByte, SQLITE_TRANSIENT); } } int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *db){ int rc; /* Return code */ |
︙ | ︙ |
Changes to ext/fts5/fts5_tokenize.c.
︙ | ︙ | |||
659 660 661 662 663 664 665 | int bCons = bPrevCons; /* Scan for a vowel */ for(i=0; i<nStem; i++){ if( 0==(bCons = !fts5PorterIsVowel(zStem[i], bCons)) ) break; } | | | 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 | int bCons = bPrevCons; /* Scan for a vowel */ for(i=0; i<nStem; i++){ if( 0==(bCons = !fts5PorterIsVowel(zStem[i], bCons)) ) break; } /* Scan for a consonant */ for(i++; i<nStem; i++){ if( (bCons = !fts5PorterIsVowel(zStem[i], bCons)) ) return i+1; } return 0; } /* porter rule condition: (m > 0) */ |
︙ | ︙ |
Changes to ext/fts5/fts5_unicode2.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | /* ** If the argument is a codepoint corresponding to a lowercase letter ** in the ASCII range with a diacritic added, return the codepoint ** of the ASCII letter only. For example, if passed 235 - "LATIN ** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* ** If the argument is a codepoint corresponding to a lowercase letter ** in the ASCII range with a diacritic added, return the codepoint ** of the ASCII letter only. For example, if passed 235 - "LATIN ** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER ** E"). The results of passing a codepoint that corresponds to an ** uppercase letter are undefined. */ static int fts5_remove_diacritic(int c, int bComplex){ unsigned short aDia[] = { 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, |
︙ | ︙ |
Changes to ext/fts5/fts5_vocab.c.
︙ | ︙ | |||
58 59 60 61 62 63 64 | sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */ Fts5Table *pFts5; /* Associated FTS5 table */ int bEof; /* True if this cursor is at EOF */ Fts5IndexIter *pIter; /* Term/rowid iterator object */ int nLeTerm; /* Size of zLeTerm in bytes */ | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */ Fts5Table *pFts5; /* Associated FTS5 table */ int bEof; /* True if this cursor is at EOF */ Fts5IndexIter *pIter; /* Term/rowid iterator object */ int nLeTerm; /* Size of zLeTerm in bytes */ char *zLeTerm; /* (term <= $zLeTerm) parameter, or NULL */ /* These are used by 'col' tables only */ int iCol; i64 *aCnt; i64 *aDoc; /* Output values used by all tables. */ |
︙ | ︙ |
Changes to ext/fts5/mkportersteps.tcl.
︙ | ︙ | |||
213 214 215 216 217 218 219 | } puts [string trim { /* ** GENERATED CODE ENDS HERE (mkportersteps.tcl) *************************************************************************** **************************************************************************/ }] | < < < | 213 214 215 216 217 218 219 | } puts [string trim { /* ** GENERATED CODE ENDS HERE (mkportersteps.tcl) *************************************************************************** **************************************************************************/ }] |
Changes to ext/fts5/test/fts5_common.tcl.
︙ | ︙ | |||
640 641 642 643 644 645 646 | } } sqlite3_fts5_create_tokenizer db tclnum tclnum_create } # # End of tokenizer code. #------------------------------------------------------------------------- | < | 640 641 642 643 644 645 646 | } } sqlite3_fts5_create_tokenizer db tclnum tclnum_create } # # End of tokenizer code. #------------------------------------------------------------------------- |
Changes to ext/fts5/test/fts5aux.test.
︙ | ︙ | |||
304 305 306 307 308 309 310 | } {1 {unable to use function firstcol in the requested context}} do_catchsql_test 10.1.4 { SELECT group_concat(firstcol(t1), '.') FROM t1 GROUP BY rowid } {1 {unable to use function firstcol in the requested context}} finish_test | < | 304 305 306 307 308 309 310 | } {1 {unable to use function firstcol in the requested context}} do_catchsql_test 10.1.4 { SELECT group_concat(firstcol(t1), '.') FROM t1 GROUP BY rowid } {1 {unable to use function firstcol in the requested context}} finish_test |
Changes to ext/fts5/test/fts5content.test.
︙ | ︙ | |||
290 291 292 293 294 295 296 | SELECT count(*) FROM t1; } {1 {recursively defined fts5 content table}} do_catchsql_test 7.2.5 { SELECT * FROM t1('abc') ORDER BY rank; } {1 {recursively defined fts5 content table}} finish_test | < | 290 291 292 293 294 295 296 | SELECT count(*) FROM t1; } {1 {recursively defined fts5 content table}} do_catchsql_test 7.2.5 { SELECT * FROM t1('abc') ORDER BY rank; } {1 {recursively defined fts5 content table}} finish_test |
Changes to ext/fts5/test/fts5corrupt3.test.
︙ | ︙ | |||
10322 10323 10324 10325 10326 10327 10328 | do_catchsql_test 69.2 { SELECT * FROM t1 WHERE a MATCH 'fx*' } {1 {database disk image is malformed}} sqlite3_fts5_may_be_corrupt 0 finish_test | < | 10322 10323 10324 10325 10326 10327 10328 | do_catchsql_test 69.2 { SELECT * FROM t1 WHERE a MATCH 'fx*' } {1 {database disk image is malformed}} sqlite3_fts5_may_be_corrupt 0 finish_test |
Changes to ext/fts5/test/fts5corrupt4.test.
︙ | ︙ | |||
54 55 56 57 58 59 60 | execsql ROLLBACK } } {} } sqlite3_fts5_may_be_corrupt 0 finish_test | < | 54 55 56 57 58 59 60 | execsql ROLLBACK } } {} } sqlite3_fts5_may_be_corrupt 0 finish_test |
Changes to ext/fts5/test/fts5interrupt.test.
︙ | ︙ | |||
60 61 62 63 64 65 66 | } set {} {} } {} } } finish_test | < | 60 61 62 63 64 65 66 | } set {} {} } {} } } finish_test |
Changes to ext/fts5/test/fts5misc.test.
︙ | ︙ | |||
320 321 322 323 324 325 326 | SELECT * FROM ft NATURAL JOIN t1 WHERE ft MATCH('b') } {b world {}} do_execsql_test 12.3 { SELECT * FROM t2 JOIN ft USING (ft) } {3 4 b b} finish_test | < | 320 321 322 323 324 325 326 | SELECT * FROM ft NATURAL JOIN t1 WHERE ft MATCH('b') } {b world {}} do_execsql_test 12.3 { SELECT * FROM t2 JOIN ft USING (ft) } {3 4 b b} finish_test |
Changes to ext/fts5/test/fts5multi.test.
︙ | ︙ | |||
92 93 94 95 96 97 98 | 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 | < | 92 93 94 95 96 97 98 | 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/fts5savepoint.test.
︙ | ︙ | |||
78 79 80 81 82 83 84 | INSERT INTO vt0 VALUES('x'); COMMIT; INSERT INTO vt0(vt0) VALUES('integrity-check'); } } finish_test | < | 78 79 80 81 82 83 84 | INSERT INTO vt0 VALUES('x'); COMMIT; INSERT INTO vt0(vt0) VALUES('integrity-check'); } } finish_test |
Changes to ext/fts5/test/fts5simple3.test.
︙ | ︙ | |||
77 78 79 80 81 82 83 | INSERT INTO x3 VALUES('a b c'); INSERT INTO x3 VALUES('c b a'); INSERT INTO x3 VALUES('o t t'); SELECT * FROM x3('x OR y OR z'); } #------------------------------------------------------------------------- | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | INSERT INTO x3 VALUES('a b c'); INSERT INTO x3 VALUES('c b a'); INSERT INTO x3 VALUES('o t t'); SELECT * FROM x3('x OR y OR z'); } #------------------------------------------------------------------------- # Test that a crash occurring when the second or subsequent tokens in a # phrase matched zero rows has been fixed. # do_execsql_test 4.0 { CREATE VIRTUAL TABLE t1 USING fts5(x); INSERT INTO t1 VALUES('ab'); INSERT INTO t1 VALUES('cd'); INSERT INTO t1 VALUES('ab cd'); |
︙ | ︙ |
Changes to ext/fts5/test/fts5umlaut.test.
︙ | ︙ | |||
58 59 60 61 62 63 64 | DELETE FROM t2; INSERT INTO t2(rowid, x) VALUES (1, $q); SELECT count(*) FROM t2('Ha Noi') } $res2 } finish_test | < | 58 59 60 61 62 63 64 | DELETE FROM t2; INSERT INTO t2(rowid, x) VALUES (1, $q); SELECT count(*) FROM t2('Ha Noi') } $res2 } finish_test |
Changes to ext/fts5/tool/fts5speed.tcl.
︙ | ︙ | |||
56 57 58 59 60 61 62 | } else { puts "result: [db eval $sql]" } for {set i 1} {$i < $nRepeat} {incr i} { db eval $sql } | < < | 56 57 58 59 60 61 62 | } else { puts "result: [db eval $sql]" } for {set i 1} {$i < $nRepeat} {incr i} { db eval $sql } |
Changes to ext/fts5/tool/fts5txt2db.tcl.
︙ | ︙ | |||
220 221 222 223 224 225 226 | foreach c $cols s $A(colsize) { set R($c) [lrange $tokens $i [expr $i+$s-1]] incr i $s } db eval $sql } if {$A(trans)} { db eval COMMIT } | < < < | 220 221 222 223 224 225 226 | foreach c $cols s $A(colsize) { set R($c) [lrange $tokens $i [expr $i+$s-1]] incr i $s } db eval $sql } if {$A(trans)} { db eval COMMIT } |
Changes to ext/fts5/tool/loadfts5.tcl.
1 2 3 4 5 6 7 8 9 10 11 12 | proc loadfile {f} { set fd [open $f] set data [read $fd] close $fd return $data } set ::nRow 0 set ::nRowPerDot 1000 | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | proc loadfile {f} { set fd [open $f] set data [read $fd] close $fd return $data } set ::nRow 0 set ::nRowPerDot 1000 proc load_hierarchy {dir} { foreach f [glob -nocomplain -dir $dir *] { if {$::O(limit) && $::nRow>=$::O(limit)} break if {[file isdir $f]} { load_hierarchy $f } else { db eval { INSERT INTO t1 VALUES($f, loadfile($f)) } incr ::nRow if {$::O(trans) && ($::nRow % $::O(trans))==0} { db eval { COMMIT } db eval { INSERT INTO t1(t1) VALUES('integrity-check') } |
︙ | ︙ | |||
160 161 162 163 164 165 166 | } if {$O(crisismerge)>=0} { if {$O(vtab) == "fts5"} { db eval {INSERT INTO t1(t1, rank) VALUES('crisismerge', $O(crisismerge))} } else { } } | | < < < | 160 161 162 163 164 165 166 167 168 169 | } if {$O(crisismerge)>=0} { if {$O(vtab) == "fts5"} { db eval {INSERT INTO t1(t1, rank) VALUES('crisismerge', $O(crisismerge))} } else { } } load_hierarchy [lindex $argv end] db eval COMMIT puts "" |
Changes to ext/fts5/tool/showfts5.tcl.
︙ | ︙ | |||
86 87 88 89 90 91 92 | if {$O(segments)} { puts "" db eval "SELECT fts5_decode(rowid, block) AS d FROM ${tbl}_data WHERE id>10" { puts $d } } | < < < < < | 86 87 88 89 90 91 92 | if {$O(segments)} { puts "" db eval "SELECT fts5_decode(rowid, block) AS d FROM ${tbl}_data WHERE id>10" { puts $d } } |
Changes to ext/icu/README.txt.
︙ | ︙ | |||
87 88 89 90 91 92 93 | australian_penpal_name TEXT COLLATE australian, turkish_penpal_name TEXT COLLATE turkish ); 1.4 SQL REGEXP Operator This extension provides an implementation of the SQL binary | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | australian_penpal_name TEXT COLLATE australian, turkish_penpal_name TEXT COLLATE turkish ); 1.4 SQL REGEXP Operator This extension provides an implementation of the SQL binary comparison operator "REGEXP", based on the regular expression functions provided by the ICU library. The syntax of the operator is as described in SQLite documentation: <string> REGEXP <re-pattern> This extension uses the ICU defaults for regular expression matching behavior. Specifically, this means that: |
︙ | ︙ |
Changes to ext/lsm1/lsm-test/lsmtest5.c.
︙ | ︙ | |||
553 554 555 556 557 558 559 | iPrng += sizeof(aRnd); snprintf(aValue, sizeof(aValue), "%d.%s", iThread, aRnd); nWrite += dbWriteOperation(&p->param, pDb, iKey, aValue, &rc); } } testClose(&pDb); | | | 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | iPrng += sizeof(aRnd); snprintf(aValue, sizeof(aValue), "%d.%s", iThread, aRnd); nWrite += dbWriteOperation(&p->param, pDb, iKey, aValue, &rc); } } testClose(&pDb); /* If an error has occurred, set the thread error code and the threadset ** halt flag to tell the other test threads to halt. Otherwise, set the ** thread error code to 0 and post a message with the number of read ** and write operations completed. */ if( rc ){ testThreadSetResult(pThreadSet, iThread, rc, 0); testThreadSetHalt(pThreadSet); }else{ |
︙ | ︙ |
Changes to ext/lsm1/lsmInt.h.
︙ | ︙ | |||
564 565 566 567 568 569 570 | u32 iBlk; /* Block number */ i64 iId; /* Largest snapshot id to use this block */ }; /* ** A snapshot of a database. A snapshot contains all the information required ** to read or write a database file on disk. See the description of struct | | | 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 | u32 iBlk; /* Block number */ i64 iId; /* Largest snapshot id to use this block */ }; /* ** A snapshot of a database. A snapshot contains all the information required ** to read or write a database file on disk. See the description of struct ** Database below for further details. */ struct Snapshot { Database *pDatabase; /* Database this snapshot belongs to */ u32 iCmpId; /* Id of compression scheme */ Level *pLevel; /* Pointer to level 0 of snapshot (or NULL) */ i64 iId; /* Snapshot id */ i64 iLogOff; /* Log file offset */ |
︙ | ︙ |
Changes to ext/lsm1/lsm_ckpt.c.
︙ | ︙ | |||
165 166 167 168 169 170 171 | ** The actual value used may be configured using LSM_CONFIG_MAX_FREELIST. */ /* ** The argument to this macro must be of type u32. On a little-endian ** architecture, it returns the u32 value that results from interpreting ** the 4 bytes as a big-endian value. On a big-endian architecture, it | | | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | ** The actual value used may be configured using LSM_CONFIG_MAX_FREELIST. */ /* ** The argument to this macro must be of type u32. On a little-endian ** architecture, it returns the u32 value that results from interpreting ** the 4 bytes as a big-endian value. On a big-endian architecture, it ** returns the value that would be produced by interpreting the 4 bytes ** of the input value as a little-endian integer. */ #define BYTESWAP32(x) ( \ (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8) \ + (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24) \ ) |
︙ | ︙ |
Changes to ext/lsm1/lsm_file.c.
︙ | ︙ | |||
643 644 645 646 647 648 649 | /* Make a copy of the database and log file names. */ memcpy(pFS->zDb, zDb, nDb+1); memcpy(pFS->zLog, zDb, nDb); memcpy(&pFS->zLog[nDb], "-log", 5); /* Allocate the hash-table here. At some point, it should be changed | | | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 | /* Make a copy of the database and log file names. */ memcpy(pFS->zDb, zDb, nDb+1); memcpy(pFS->zLog, zDb, nDb); memcpy(&pFS->zLog[nDb], "-log", 5); /* Allocate the hash-table here. At some point, it should be changed ** so that it can grow dynamically. */ pFS->nCacheMax = 2048*1024 / pFS->nPagesize; pFS->nHash = 4096; pFS->apHash = lsmMallocZeroRc(pDb->pEnv, sizeof(Page *) * pFS->nHash, &rc); /* Open the database file */ pLsmFile = lsmDbRecycleFd(pDb); if( pLsmFile ){ |
︙ | ︙ | |||
789 790 791 792 793 794 795 | ** when the FileSystem object is destroyed, as this would cause any POSIX ** locks held by the other connections to be silently dropped (see "man close" ** for details). Instead, the file-descriptor is stored in a list by the ** lsm_shared.c module until it is either closed or reused. ** ** This function returns a pointer to an object that can be linked into ** the list described above. The returned object now 'owns' the database | | | 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 | ** when the FileSystem object is destroyed, as this would cause any POSIX ** locks held by the other connections to be silently dropped (see "man close" ** for details). Instead, the file-descriptor is stored in a list by the ** lsm_shared.c module until it is either closed or reused. ** ** This function returns a pointer to an object that can be linked into ** the list described above. The returned object now 'owns' the database ** file descriptor, so that when the FileSystem object is destroyed, it ** will not be closed. ** ** This function may be called at most once in the life-time of a ** FileSystem object. The results of any operations involving the database ** file descriptor are undefined once this function has been called. ** ** None of this is necessary on non-POSIX systems. But we do it anyway in |
︙ | ︙ |
Changes to ext/lsm1/lsm_log.c.
︙ | ︙ | |||
754 755 756 757 758 759 760 | pMark->iOff = pLog->iOff + pLog->buf.n; pMark->cksum0 = pLog->cksum0; pMark->cksum1 = pLog->cksum1; } /* | | | 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 | pMark->iOff = pLog->iOff + pLog->buf.n; pMark->cksum0 = pLog->cksum0; pMark->cksum1 = pLog->cksum1; } /* ** Seek (rewind) back to the log file offset stored by an earlier call to ** lsmLogTell() in *pMark. */ void lsmLogSeek( lsm_db *pDb, /* Database handle */ LogMark *pMark /* Object containing log offset to seek to */ ){ LogWriter *pLog; |
︙ | ︙ |
Changes to ext/lsm1/lsm_main.c.
︙ | ︙ | |||
767 768 769 770 771 772 773 | } /* Allocate the multi-cursor. */ if( rc==LSM_OK ){ rc = lsmMCursorNew(pDb, &pCsr); } | | | 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 | } /* Allocate the multi-cursor. */ if( rc==LSM_OK ){ rc = lsmMCursorNew(pDb, &pCsr); } /* If an error has occurred, set the output to NULL and delete any partially ** allocated cursor. If this means there are no open cursors, release the ** client snapshot. */ if( rc!=LSM_OK ){ lsmMCursorClose(pCsr, 0); dbReleaseClientSnapshot(pDb); } |
︙ | ︙ |
Changes to ext/lsm1/lsm_shared.c.
︙ | ︙ | |||
1959 1960 1961 1962 1963 1964 1965 | u32 nWrite = 0; /* Number of pages checkpointed */ /* Attempt the checkpoint. If successful, nWrite is set to the number of ** pages written between this and the previous checkpoint. */ rc = lsmCheckpointWrite(pDb, &nWrite); /* If required, calculate the output variable (KB of data checkpointed). | | | 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 | u32 nWrite = 0; /* Number of pages checkpointed */ /* Attempt the checkpoint. If successful, nWrite is set to the number of ** pages written between this and the previous checkpoint. */ rc = lsmCheckpointWrite(pDb, &nWrite); /* If required, calculate the output variable (KB of data checkpointed). ** Set it to zero if an error occurred. */ if( pnKB ){ int nKB = 0; if( rc==LSM_OK && nWrite ){ nKB = (((i64)nWrite * lsmFsPageSize(pDb->pFS)) + 1023) / 1024; } *pnKB = nKB; } |
︙ | ︙ |
Changes to ext/lsm1/lsm_sorted.c.
︙ | ︙ | |||
2648 2649 2650 2651 2652 2653 2654 | } int lsmSortedLoadFreelist( lsm_db *pDb, /* Database handle (must be worker) */ void **ppVal, /* OUT: Blob containing LSM free-list */ int *pnVal /* OUT: Size of *ppVal blob in bytes */ ){ | | | 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 | } int lsmSortedLoadFreelist( lsm_db *pDb, /* Database handle (must be worker) */ void **ppVal, /* OUT: Blob containing LSM free-list */ int *pnVal /* OUT: Size of *ppVal blob in bytes */ ){ MultiCursor *pCsr; /* Cursor used to retrieve free-list */ int rc = LSM_OK; /* Return Code */ assert( pDb->pWorker ); assert( *ppVal==0 && *pnVal==0 ); pCsr = multiCursorNew(pDb, &rc); if( pCsr ){ |
︙ | ︙ | |||
3580 3581 3582 3583 3584 3585 3586 | LsmPgno iKeyPg, void *pKey, int nKey ){ Hierarchy *p = &pMW->hier; lsm_db *pDb = pMW->pDb; /* Database handle */ int rc = LSM_OK; /* Return Code */ | | | 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 | LsmPgno iKeyPg, void *pKey, int nKey ){ Hierarchy *p = &pMW->hier; lsm_db *pDb = pMW->pDb; /* Database handle */ int rc = LSM_OK; /* Return Code */ int iLevel; /* Level of b-tree hierarchy to write to */ int nData; /* Size of aData[] in bytes */ u8 *aData; /* Page data for level iLevel */ int iOff; /* Offset on b-tree page to write record to */ int nRec; /* Initial number of records on b-tree page */ /* iKeyPg should be zero for an ordinary b-tree key, or non-zero for an ** indirect key. The flags byte for an indirect key is 0x00. */ |
︙ | ︙ | |||
3980 3981 3982 3983 3984 3985 3986 | nRec = pageGetNRec(aData, nData); iFPtr = (int)pageGetPtr(aData, nData); iRPtr = iPtr - iFPtr; } /* Figure out how much space is required by the new record. The space ** required is divided into two sections: the header and the body. The | | | 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 | nRec = pageGetNRec(aData, nData); iFPtr = (int)pageGetPtr(aData, nData); iRPtr = iPtr - iFPtr; } /* Figure out how much space is required by the new record. The space ** required is divided into two sections: the header and the body. The ** header consists of the initial varint fields. The body are the blobs ** of data that correspond to the key and value data. The entire header ** must be stored on the page. The body may overflow onto the next and ** subsequent pages. ** ** The header space is: ** ** 1) record type - 1 byte. |
︙ | ︙ |
Changes to ext/lsm1/lsm_vtab.c.
︙ | ︙ | |||
78 79 80 81 82 83 84 | ** is T/6. Type value 0 means that the value is an integer whose actual ** values is T/6 and there is no content. The type-value-0 integer format ** only works for integers in the range of 0 through 40. ** ** There is no content for NULL or type-0 integers. For BLOB and TEXT ** values, the content is the blob data or the UTF-8 text data. For ** non-negative integers X, the content is a variable-length integer X*2. | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | ** is T/6. Type value 0 means that the value is an integer whose actual ** values is T/6 and there is no content. The type-value-0 integer format ** only works for integers in the range of 0 through 40. ** ** There is no content for NULL or type-0 integers. For BLOB and TEXT ** values, the content is the blob data or the UTF-8 text data. For ** non-negative integers X, the content is a variable-length integer X*2. ** For negative integers Y, the content is variable-length integer (1-Y)*2+1. ** For FLOAT values, the content is the IEEE754 floating point value in ** native byte-order. This means that FLOAT values will be corrupted when ** database file is moved between big-endian and little-endian machines. */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #include "lsm.h" |
︙ | ︙ |
Changes to ext/misc/amatch.c.
︙ | ︙ | |||
480 481 482 483 484 485 486 | */ struct amatch_rule { amatch_rule *pNext; /* Next rule in order of increasing rCost */ char *zFrom; /* Transform from (a string from user input) */ amatch_cost rCost; /* Cost of this transformation */ amatch_langid iLang; /* The langauge to which this rule belongs */ amatch_len nFrom, nTo; /* Length of the zFrom and zTo strings */ | | | 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | */ struct amatch_rule { amatch_rule *pNext; /* Next rule in order of increasing rCost */ char *zFrom; /* Transform from (a string from user input) */ amatch_cost rCost; /* Cost of this transformation */ amatch_langid iLang; /* The langauge to which this rule belongs */ amatch_len nFrom, nTo; /* Length of the zFrom and zTo strings */ char zTo[4]; /* Transform to V.W value (extra space appended) */ }; /* ** A amatch virtual-table object */ struct amatch_vtab { sqlite3_vtab base; /* Base class - must be first */ |
︙ | ︙ |
Changes to ext/misc/btreeinfo.c.
︙ | ︙ | |||
45 46 47 48 49 50 51 | ** ** The sqlite_dbpage virtual table must be available for this virtual table ** to operate. ** ** USAGE EXAMPLES: ** ** Show the table btrees in a schema order with the tables with the most | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | ** ** The sqlite_dbpage virtual table must be available for this virtual table ** to operate. ** ** USAGE EXAMPLES: ** ** Show the table btrees in a schema order with the tables with the most ** rows occurring first: ** ** SELECT name, nEntry ** FROM sqlite_btreeinfo ** WHERE type='table' ** ORDER BY nEntry DESC, name; ** ** Show the names of all WITHOUT ROWID tables: |
︙ | ︙ | |||
97 98 99 100 101 102 103 | int szPage; /* size of a btree page. 0 if unknown */ char *zSchema; /* Schema being interrogated */ }; /* The sqlite_btreeinfo table */ struct BinfoTable { sqlite3_vtab base; /* Base class. Must be first */ | | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | int szPage; /* size of a btree page. 0 if unknown */ char *zSchema; /* Schema being interrogated */ }; /* The sqlite_btreeinfo table */ struct BinfoTable { sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; /* The database connection */ }; /* ** Connect to the sqlite_btreeinfo virtual table. */ static int binfoConnect( sqlite3 *db, |
︙ | ︙ |
Changes to ext/misc/cksumvfs.c.
︙ | ︙ | |||
43 44 45 46 47 48 49 | ** to the sqlite3_load_extension() API call. Then you invoke the ** sqlite3_load_extension() API and shutdown the dummy database ** connection. All subsequent database connections that are opened ** will include this extension. For example: ** ** sqlite3 *db; ** sqlite3_open(":memory:", &db); | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | ** to the sqlite3_load_extension() API call. Then you invoke the ** sqlite3_load_extension() API and shutdown the dummy database ** connection. All subsequent database connections that are opened ** will include this extension. For example: ** ** sqlite3 *db; ** sqlite3_open(":memory:", &db); ** sqlite3_load_extension(db, "./cksumvfs"); ** sqlite3_close(db); ** ** If this extension is compiled with -DSQLITE_CKSUMVFS_STATIC and ** statically linked against the application, initialize it using ** a single API call as follows: ** ** sqlite3_cksumvfs_init(); |
︙ | ︙ |
Changes to ext/misc/csv.c.
︙ | ︙ | |||
310 311 312 313 314 315 316 | char *zData; /* Raw CSV data in lieu of zFilename */ long iStart; /* Offset to start of data in zFilename */ int nCol; /* Number of columns in the CSV file */ unsigned int tstFlags; /* Bit values used for testing */ } CsvTable; /* Allowed values for tstFlags */ | | | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | char *zData; /* Raw CSV data in lieu of zFilename */ long iStart; /* Offset to start of data in zFilename */ int nCol; /* Number of columns in the CSV file */ unsigned int tstFlags; /* Bit values used for testing */ } CsvTable; /* Allowed values for tstFlags */ #define CSVTEST_FIDX 0x0001 /* Pretend that constrained searches cost less*/ /* A cursor for the CSV virtual table */ typedef struct CsvCursor { sqlite3_vtab_cursor base; /* Base class. Must be first */ CsvReader rdr; /* The CsvReader object */ char **azVal; /* Value of the current row */ int *aLen; /* Length of each entry */ |
︙ | ︙ | |||
389 390 391 392 393 394 395 | ** Return 1 if the parameter is seen, or 0 if not. 1 is returned ** even if there is an error. If an error occurs, then an error message ** is left in p->zErr. If there are no errors, p->zErr[0]==0. */ static int csv_string_parameter( CsvReader *p, /* Leave the error message here, if there is one */ const char *zParam, /* Parameter we are checking for */ | | | 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | ** Return 1 if the parameter is seen, or 0 if not. 1 is returned ** even if there is an error. If an error occurs, then an error message ** is left in p->zErr. If there are no errors, p->zErr[0]==0. */ static int csv_string_parameter( CsvReader *p, /* Leave the error message here, if there is one */ const char *zParam, /* Parameter we are checking for */ const char *zArg, /* Raw text of the virtual table argument */ char **pzVal /* Write the dequoted string value here */ ){ const char *zValue; zValue = csv_parameter(zParam,(int)strlen(zParam),zArg); if( zValue==0 ) return 0; p->zErr[0] = 0; if( *pzVal ){ |
︙ | ︙ | |||
835 836 837 838 839 840 841 | sqlite3_index_info *pIdxInfo ){ pIdxInfo->estimatedCost = 1000000; #ifdef SQLITE_TEST if( (((CsvTable*)tab)->tstFlags & CSVTEST_FIDX)!=0 ){ /* The usual (and sensible) case is to always do a full table scan. ** The code in this branch only runs when testflags=1. This code | | | 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 | sqlite3_index_info *pIdxInfo ){ pIdxInfo->estimatedCost = 1000000; #ifdef SQLITE_TEST if( (((CsvTable*)tab)->tstFlags & CSVTEST_FIDX)!=0 ){ /* The usual (and sensible) case is to always do a full table scan. ** The code in this branch only runs when testflags=1. This code ** generates an artificial and unrealistic plan which is useful ** for testing virtual table logic but is not helpful to real applications. ** ** Any ==, LIKE, or GLOB constraint is marked as usable by the virtual ** table (even though it is not) and the cost of running the virtual table ** is reduced from 1 million to just 10. The constraints are *not* marked ** as omittable, however, so the query planner should still generate a ** plan that gives a correct answer, even if they plan is not optimal. |
︙ | ︙ |
Changes to ext/misc/dbdump.c.
︙ | ︙ | |||
222 223 224 225 226 227 228 | ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve ** rowids on tables where the rowid is inaccessible because there are other ** columns in the table named "rowid", "_rowid_", and "oid". */ if( isIPK ){ /* If a single PRIMARY KEY column with type INTEGER was seen, then it | | | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve ** rowids on tables where the rowid is inaccessible because there are other ** columns in the table named "rowid", "_rowid_", and "oid". */ if( isIPK ){ /* If a single PRIMARY KEY column with type INTEGER was seen, then it ** might be an alias for the ROWID. But it might also be a WITHOUT ROWID ** table or a INTEGER PRIMARY KEY DESC column, neither of which are ** ROWID aliases. To distinguish these cases, check to see if ** there is a "pk" entry in "PRAGMA index_list". There will be ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID. */ zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" " WHERE origin='pk'", zTab); |
︙ | ︙ |
Changes to ext/misc/decimal.c.
︙ | ︙ | |||
463 464 465 466 467 468 469 | pB->sign = !pB->sign; decimal_add(pA, pB); decimal_result(context, pA); decimal_free(pA); decimal_free(pB); } | | | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | pB->sign = !pB->sign; decimal_add(pA, pB); decimal_result(context, pA); decimal_free(pA); decimal_free(pB); } /* Aggregate function: decimal_sum(X) ** ** Works like sum() except that it uses decimal arithmetic for unlimited ** precision. */ static void decimalSumStep( sqlite3_context *context, int argc, |
︙ | ︙ |
Changes to ext/misc/fileio.c.
︙ | ︙ | |||
497 498 499 500 501 502 503 | } } } /* ** SQL function: lsmode(MODE) ** | | | 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 | } } } /* ** SQL function: lsmode(MODE) ** ** Given a numeric st_mode from stat(), convert it into a human-readable ** text string in the style of "ls -l". */ static void lsModeFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ |
︙ | ︙ |
Changes to ext/misc/fuzzer.c.
︙ | ︙ | |||
93 94 95 96 97 98 99 | ** SELECT vocabulary.w FROM f, vocabulary ** WHERE f.word MATCH $word ** AND f.distance<=200 ** AND f.word=vocabulary.w ** LIMIT 20 ** ** The query above gives the 20 closest words to the $word being tested. | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | ** SELECT vocabulary.w FROM f, vocabulary ** WHERE f.word MATCH $word ** AND f.distance<=200 ** AND f.word=vocabulary.w ** LIMIT 20 ** ** The query above gives the 20 closest words to the $word being tested. ** (Note that for good performance, the vocabulary.w column should be ** indexed.) ** ** A similar query can be used to find all words in the dictionary that ** begin with some prefix $prefix: ** ** SELECT vocabulary.w FROM f, vocabulary ** WHERE f.word MATCH $prefix |
︙ | ︙ |
Changes to ext/misc/ieee754.c.
︙ | ︙ | |||
69 70 71 72 73 74 75 | ** point value (the value 47.49 is used in the example) do: ** ** WITH c(n) AS (VALUES(47.49)) ** ---------------^^^^^---- Replace with whatever you want ** SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v) ** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n); ** | | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | ** point value (the value 47.49 is used in the example) do: ** ** WITH c(n) AS (VALUES(47.49)) ** ---------------^^^^^---- Replace with whatever you want ** SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v) ** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n); ** ** Here is a query to show various boundary values for the binary64 ** number format: ** ** WITH c(name,bin) AS (VALUES ** ('minimum positive value', x'0000000000000001'), ** ('maximum subnormal value', x'000fffffffffffff'), ** ('minimum positive normal value', x'0010000000000000'), ** ('maximum value', x'7fefffffffffffff')) ** SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v) ** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin); ** */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 |
︙ | ︙ |
Changes to ext/misc/json1.c.
︙ | ︙ | |||
1947 1948 1949 1950 1951 1952 1953 | 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 | | | 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 | 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 initialize 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; |
︙ | ︙ |
Changes to ext/misc/nextchar.c.
︙ | ︙ | |||
16 17 18 19 20 21 22 | ** string A given the vocabulary in T.F. If the W value exists and is a ** non-empty string, then it is an SQL expression that limits the entries ** in T.F that will be considered. If C exists and is a non-empty string, ** then it is the name of the collating sequence to use for comparison. If ** ** Only the first three arguments are required. If the C parameter is ** omitted or is NULL or is an empty string, then the default collating | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ** string A given the vocabulary in T.F. If the W value exists and is a ** non-empty string, then it is an SQL expression that limits the entries ** in T.F that will be considered. If C exists and is a non-empty string, ** then it is the name of the collating sequence to use for comparison. If ** ** Only the first three arguments are required. If the C parameter is ** omitted or is NULL or is an empty string, then the default collating ** sequence of T.F is used for comparison. If the W parameter is omitted ** or is NULL or is an empty string, then no filtering of the output is ** done. ** ** The T.F column should be indexed using collation C or else this routine ** will be quite slow. ** ** For example, suppose an application has a dictionary like this: |
︙ | ︙ |
Changes to ext/misc/sha1.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | ** ** sha1(X) ** sha1_query(Y) ** ** The sha1(X) function computes the SHA1 hash of the input X, or NULL if ** X is NULL. ** | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | ** ** sha1(X) ** sha1_query(Y) ** ** The sha1(X) function computes the SHA1 hash of the input X, or NULL if ** X is NULL. ** ** The sha1_query(Y) function evaluates all queries in the SQL statements of Y ** and returns a hash of their results. */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #include <assert.h> #include <string.h> #include <stdarg.h> |
︙ | ︙ |
Changes to ext/misc/shathree.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | ** ** sha3(X,SIZE) ** sha3_query(Y,SIZE) ** ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if ** X is NULL. ** | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | ** ** sha3(X,SIZE) ** sha3_query(Y,SIZE) ** ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if ** X is NULL. ** ** The sha3_query(Y) function evaluates all queries in the SQL statements of Y ** and returns a hash of their results. ** ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm ** is used. If SIZE is included it must be one of the integers 224, 256, ** 384, or 512, to determine SHA3 hash variant that is computed. */ #include "sqlite3ext.h" |
︙ | ︙ | |||
567 568 569 570 571 572 573 | ** B means blobs of <size> bytes. T means text rendered as <size> ** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII ** text integers. ** ** For each SQL statement in the X input, there is one S segment. Each ** S segment is followed by zero or more R segments, one for each row in the ** result set. After each R, there are one or more N, I, F, B, or T segments, | | | 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 | ** B means blobs of <size> bytes. T means text rendered as <size> ** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII ** text integers. ** ** For each SQL statement in the X input, there is one S segment. Each ** S segment is followed by zero or more R segments, one for each row in the ** result set. After each R, there are one or more N, I, F, B, or T segments, ** one for each column in the result set. Segments are concatenated directly ** with no delimiters of any kind. */ static void sha3QueryFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ |
︙ | ︙ |
Changes to ext/misc/spellfix.c.
︙ | ︙ | |||
332 333 334 335 336 337 338 | return 40; } if( classFrom>=CCLASS_B && classFrom<=CCLASS_Y && classTo>=CCLASS_B && classTo<=CCLASS_Y ){ /* Convert from one consonant to another, but in a different class */ return 75; } | | | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | return 40; } if( classFrom>=CCLASS_B && classFrom<=CCLASS_Y && classTo>=CCLASS_B && classTo<=CCLASS_Y ){ /* Convert from one consonant to another, but in a different class */ return 75; } /* Any other substitution */ return 100; } /* ** Given two strings zA and zB which are pure ASCII, return the cost ** of transforming zA into zB. If zA ends with '*' assume that it is ** a prefix of zB and give only minimal penalty for extra characters |
︙ | ︙ | |||
858 859 860 861 862 863 864 | /* ** Return TRUE (non-zero) of the next FROM character and the next TO ** character are the same. */ static int matchFromTo( EditDist3FromString *pStr, /* Left hand string */ int n1, /* Index of comparison character on the left */ | | | | 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 | /* ** Return TRUE (non-zero) of the next FROM character and the next TO ** character are the same. */ static int matchFromTo( EditDist3FromString *pStr, /* Left hand string */ int n1, /* Index of comparison character on the left */ const char *z2, /* Right-hand comparison character */ int n2 /* Bytes remaining in z2[] */ ){ int b1 = pStr->a[n1].nByte; if( b1>n2 ) return 0; assert( b1>0 ); if( pStr->z[n1]!=z2[0] ) return 0; if( strncmp(pStr->z+n1, z2, b1)!=0 ) return 0; return 1; } /* ** Delete an EditDist3FromString object */ static void editDist3FromStringDelete(EditDist3FromString *p){ int i; if( p ){ for(i=0; i<p->n; i++){ sqlite3_free(p->a[i].apDel); sqlite3_free(p->a[i].apSubst); |
︙ | ︙ | |||
2361 2362 2363 2364 2365 2366 2367 | /* ** A structure used to pass information from spellfix1FilterForMatch() ** into spellfix1RunQuery(). */ typedef struct MatchQuery { spellfix1_cursor *pCur; /* The cursor being queried */ | | | 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 | /* ** A structure used to pass information from spellfix1FilterForMatch() ** into spellfix1RunQuery(). */ typedef struct MatchQuery { spellfix1_cursor *pCur; /* The cursor being queried */ sqlite3_stmt *pStmt; /* shadow table query statement */ char zHash[SPELLFIX_MX_HASH]; /* The current phonehash for zPattern */ const char *zPattern; /* Transliterated input string */ int nPattern; /* Length of zPattern */ EditDist3FromString *pMatchStr3; /* Original unicode string */ EditDist3Config *pConfig3; /* Edit-distance cost coefficients */ const EditDist3Lang *pLang; /* The selected language coefficients */ int iLang; /* The language id */ |
︙ | ︙ |
Changes to ext/misc/totype.c.
︙ | ︙ | |||
342 343 344 345 346 347 348 | result = (double)s; } } /* store the result */ *pResult = result; | | | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | result = (double)s; } } /* store the result */ *pResult = result; /* return true if number and no extra non-whitespace characters after */ return z>=zEnd && nDigits>0 && eValid && nonNum==0; } /* ** tointeger(X): If X is any value (integer, double, blob, or string) that ** can be losslessly converted into an integer, then make the conversion and ** return the result. Otherwise, return NULL. |
︙ | ︙ |
Changes to ext/misc/uint.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** ** This SQLite extension implements the UINT collating sequence. ** ** UINT works like BINARY for text, except that embedded strings ** of digits compare in numeric order. ** ** * Leading zeros are handled properly, in the sense that | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** ** This SQLite extension implements the UINT collating sequence. ** ** UINT works like BINARY for text, except that embedded strings ** of digits compare in numeric order. ** ** * Leading zeros are handled properly, in the sense that ** they do not mess of the magnitude comparison of embedded ** strings of digits. "x00123y" is equal to "x123y". ** ** * Only unsigned integers are recognized. Plus and minus ** signs are ignored. Decimal points and exponential notation ** are ignored. ** ** * Embedded integers can be of arbitrary length. Comparison |
︙ | ︙ |
Changes to ext/misc/unionvtab.c.
︙ | ︙ | |||
34 35 36 37 38 39 40 | ** ** UNIONVTAB ** ** A "unionvtab" virtual table is created as follows: ** ** CREATE VIRTUAL TABLE <name> USING unionvtab(<sql-statement>); ** | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | ** ** UNIONVTAB ** ** A "unionvtab" virtual table is created as follows: ** ** CREATE VIRTUAL TABLE <name> USING unionvtab(<sql-statement>); ** ** The implementation evaluates <sql statement> whenever a unionvtab virtual ** table is created or opened. It should return one row for each source ** database table. The four columns required of each row are: ** ** 1. The name of the database containing the table ("main" or "temp" or ** the name of an attached database). Or NULL to indicate that all ** databases should be searched for the table in the usual fashion. ** |
︙ | ︙ |
Changes to ext/misc/vfslog.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** most VFS calls to be written into a file on disk. ** ** Each database connection creates a separate log file in the same ** directory as the original database and named after the original ** database. A unique suffix is added to avoid name collisions. ** Separate log files are used so that concurrent processes do not ** try to write log operations to the same file at the same instant, | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** most VFS calls to be written into a file on disk. ** ** Each database connection creates a separate log file in the same ** directory as the original database and named after the original ** database. A unique suffix is added to avoid name collisions. ** Separate log files are used so that concurrent processes do not ** try to write log operations to the same file at the same instant, ** resulting in overwritten or commingled log text. ** ** Each individual log file records operations by a single database ** connection on both the original database and its associated rollback ** journal. ** ** The log files are in the comma-separated-value (CSV) format. The ** log files can be imported into an SQLite database using the ".import" |
︙ | ︙ |
Changes to ext/misc/vfsstat.c.
︙ | ︙ | |||
20 21 22 23 24 25 26 | /* ** This module contains code for a wrapper VFS that cause stats for ** most VFS calls to be recorded. ** ** To use this module, first compile it as a loadable extension. See ** https://www.sqlite.org/loadext.html#build for compilations instructions. ** | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /* ** This module contains code for a wrapper VFS that cause stats for ** most VFS calls to be recorded. ** ** To use this module, first compile it as a loadable extension. See ** https://www.sqlite.org/loadext.html#build for compilations instructions. ** ** After compiling, load this extension, then open database connections to be ** measured. Query usages status using the vfsstat virtual table: ** ** SELECT * FROM vfsstat; ** ** Reset counters using UPDATE statements against vfsstat: ** ** UPDATE vfsstat SET count=0; |
︙ | ︙ |
Changes to ext/misc/vtablog.c.
︙ | ︙ | |||
99 100 101 102 103 104 105 | /* Decode a parameter that requires a dequoted string. ** ** Return non-zero on an error. */ static int vtablog_string_parameter( char **pzErr, /* Leave the error message here, if there is one */ const char *zParam, /* Parameter we are checking for */ | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | /* Decode a parameter that requires a dequoted string. ** ** Return non-zero on an error. */ static int vtablog_string_parameter( char **pzErr, /* Leave the error message here, if there is one */ const char *zParam, /* Parameter we are checking for */ const char *zArg, /* Raw text of the virtual table argument */ char **pzVal /* Write the dequoted string value here */ ){ const char *zValue; zValue = vtablog_parameter(zParam,(int)strlen(zParam),zArg); if( zValue==0 ) return 0; if( *pzVal ){ *pzErr = sqlite3_mprintf("more than one '%s' parameter", zParam); |
︙ | ︙ |
Changes to ext/misc/vtshim.c.
︙ | ︙ | |||
421 422 423 424 425 426 427 | rc = pAux->pMod->xRollbackTo(pVtab->pChild, n); if( rc!=SQLITE_OK ){ VTSHIM_COPY_ERRMSG(); } return rc; } | | | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 | rc = pAux->pMod->xRollbackTo(pVtab->pChild, n); if( rc!=SQLITE_OK ){ VTSHIM_COPY_ERRMSG(); } return rc; } /* The destructor function for a disposable module */ static void vtshimAuxDestructor(void *pXAux){ vtshim_aux *pAux = (vtshim_aux*)pXAux; assert( pAux->pAllVtab==0 ); if( !pAux->bDisposed && pAux->xChildDestroy ){ pAux->xChildDestroy(pAux->pChildAux); pAux->xChildDestroy = 0; } |
︙ | ︙ |
Changes to ext/misc/zipfile.c.
︙ | ︙ | |||
548 549 550 551 552 553 554 | return ((u32)(aBuf[3]) << 24) + ((u32)(aBuf[2]) << 16) + ((u32)(aBuf[1]) << 8) + ((u32)(aBuf[0]) << 0); } /* | | | | 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 | return ((u32)(aBuf[3]) << 24) + ((u32)(aBuf[2]) << 16) + ((u32)(aBuf[1]) << 8) + ((u32)(aBuf[0]) << 0); } /* ** Write a 16-bit little endian integer into buffer aBuf. */ static void zipfilePutU16(u8 *aBuf, u16 val){ aBuf[0] = val & 0xFF; aBuf[1] = (val>>8) & 0xFF; } /* ** Write a 32-bit little endian integer into buffer aBuf. */ static void zipfilePutU32(u8 *aBuf, u32 val){ aBuf[0] = val & 0xFF; aBuf[1] = (val>>8) & 0xFF; aBuf[2] = (val>>16) & 0xFF; aBuf[3] = (val>>24) & 0xFF; } |
︙ | ︙ |
Changes to ext/rbu/rbu_common.tcl.
︙ | ︙ | |||
103 104 105 106 107 108 109 | rbu close }] {SQLITE_DONE}] uplevel [list do_execsql_test $tn.2 { PRAGMA integrity_check } ok] } | < | 103 104 105 106 107 108 109 | rbu close }] {SQLITE_DONE}] uplevel [list do_execsql_test $tn.2 { PRAGMA integrity_check } ok] } |
Changes to ext/rbu/rbuexpr.test.
︙ | ︙ | |||
86 87 88 89 90 91 92 | run_rbu test.db rbu.db } {SQLITE_DONE} sqlite3 db test.db integrity_check 2.3 finish_test | < | 86 87 88 89 90 91 92 | run_rbu test.db rbu.db } {SQLITE_DONE} sqlite3 db test.db integrity_check 2.3 finish_test |
Changes to ext/rbu/rbuvacuum4.test.
︙ | ︙ | |||
109 110 111 112 113 114 115 | INSERT INTO x VALUES('a'), ('b'), ('d'); CREATE UNIQUE INDEX y ON x(a); } do_rbu_vacuum_test 5.1 1 finish_test | < | 109 110 111 112 113 114 115 | INSERT INTO x VALUES('a'), ('b'), ('d'); CREATE UNIQUE INDEX y ON x(a); } do_rbu_vacuum_test 5.1 1 finish_test |
Changes to ext/rbu/sqlite3rbu.c.
︙ | ︙ | |||
1016 1017 1018 1019 1020 1021 1022 | } va_end(ap); return zSql; } /* ** Argument zFmt is a sqlite3_mprintf() style format string. The trailing | | | 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 | } va_end(ap); return zSql; } /* ** Argument zFmt is a sqlite3_mprintf() style format string. The trailing ** arguments are the usual substitution values. This function performs ** the printf() style substitutions and executes the result as an SQL ** statement on the RBU handles database. ** ** If an error occurs, an error code and error message is stored in the ** RBU handle. If an error has already occurred when this function is ** called, it is a no-op. */ |
︙ | ︙ | |||
1548 1549 1550 1551 1552 1553 1554 | ** ** (index-field1, index-field2, ...) > (?, ?, ...) ** ** except that the "?" placeholders are replaced with literal values. ** ** If the expression cannot be created, NULL is returned. In this case, ** the caller has to use an OFFSET clause to extract only the required | | | 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 | ** ** (index-field1, index-field2, ...) > (?, ?, ...) ** ** except that the "?" placeholders are replaced with literal values. ** ** If the expression cannot be created, NULL is returned. In this case, ** the caller has to use an OFFSET clause to extract only the required ** rows from the source table, just as it does for an RBU update operation. */ char *rbuVacuumIndexStart( sqlite3rbu *p, /* RBU handle */ RbuObjIter *pIter /* RBU iterator object */ ){ char *zOrder = 0; char *zLhs = 0; |
︙ | ︙ | |||
3845 3846 3847 3848 3849 3850 3851 | p->zVfsName = 0; } } /* ** This user-defined SQL function is invoked with a single argument - the ** name of a table expected to appear in the target database. It returns | | | 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 | p->zVfsName = 0; } } /* ** This user-defined SQL function is invoked with a single argument - the ** name of a table expected to appear in the target database. It returns ** the number of auxiliary indexes on the table. */ static void rbuIndexCntFunc( sqlite3_context *pCtx, int nVal, sqlite3_value **apVal ){ sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx); |
︙ | ︙ | |||
4690 4691 4692 4693 4694 4695 4696 | static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ rbu_file *p = (rbu_file *)pFile; int rc; rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); /* If this is an RBU vacuum operation and this is the target database, ** pretend that it has at least one page. Otherwise, SQLite will not | | | 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 | static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ rbu_file *p = (rbu_file *)pFile; int rc; rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); /* If this is an RBU vacuum operation and this is the target database, ** pretend that it has at least one page. Otherwise, SQLite will not ** check for the existence of a *-wal file. rbuVfsRead() contains ** similar logic. */ if( rc==SQLITE_OK && *pSize==0 && p->pRbu && rbuIsVacuum(p->pRbu) && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ *pSize = 1024; } |
︙ | ︙ | |||
4986 4987 4988 4989 4990 4991 4992 | ** or xOpen() to operate on the *-wal file. */ pFd->zWal = sqlite3_filename_wal(zName); } else if( flags & SQLITE_OPEN_WAL ){ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0); if( pDb ){ if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ | | | 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 | ** or xOpen() to operate on the *-wal file. */ pFd->zWal = sqlite3_filename_wal(zName); } else if( flags & SQLITE_OPEN_WAL ){ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0); if( pDb ){ if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ /* This call is to open a *-wal file. Instead, open the *-oal. This ** code ensures that the string passed to xOpen() is terminated by a ** pair of '\0' bytes in case the VFS attempts to extract a URI ** parameter from it. */ const char *zBase = zName; size_t nCopy; char *zCopy; if( rbuIsVacuum(pDb->pRbu) ){ |
︙ | ︙ |
Changes to ext/rbu/sqlite3rbu.h.
︙ | ︙ | |||
438 439 440 441 442 443 444 | SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu); /* ** Close an RBU handle. ** ** If the RBU update has been completely applied, mark the RBU database ** as fully applied. Otherwise, assuming no error has occurred, save the | | | 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu); /* ** Close an RBU handle. ** ** If the RBU update has been completely applied, mark the RBU database ** as fully applied. Otherwise, assuming no error has occurred, save the ** current state of the RBU update application to the RBU database. ** ** If an error has already occurred as part of an sqlite3rbu_step() ** or sqlite3rbu_open() call, or if one occurs within this function, an ** SQLite error code is returned. Additionally, if pzErrmsg is not NULL, ** *pzErrmsg may be set to point to a buffer containing a utf-8 formatted ** English language error message. It is the responsibility of the caller to ** eventually free any such buffer using sqlite3_free(). |
︙ | ︙ |
Changes to ext/repair/checkindex.c.
︙ | ︙ | |||
106 107 108 109 110 111 112 | #define IIC_SCANNER_SQL 4 rc = sqlite3_declare_vtab(db, "CREATE TABLE xyz(" " errmsg TEXT," /* Error message or NULL if everything is ok */ " current_key TEXT," /* SQLite quote() text of key values */ " index_name HIDDEN," /* IN: name of the index being scanned */ " after_key HIDDEN," /* IN: Start scanning after this key */ | | | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | #define IIC_SCANNER_SQL 4 rc = sqlite3_declare_vtab(db, "CREATE TABLE xyz(" " errmsg TEXT," /* Error message or NULL if everything is ok */ " current_key TEXT," /* SQLite quote() text of key values */ " index_name HIDDEN," /* IN: name of the index being scanned */ " after_key HIDDEN," /* IN: Start scanning after this key */ " scanner_sql HIDDEN" /* debugging info: SQL used for scanner */ ")" ); pRet = cidxMalloc(&rc, sizeof(CidxTable)); if( pRet ){ pRet->db = db; } |
︙ | ︙ |
Changes to ext/repair/sqlite3_checker.tcl.
︙ | ︙ | |||
209 210 211 212 213 214 215 | } if {![file readable $root_filename]} { puts stderr "File is not readable: $root_filename" exit 1 } if {[catch {sqlite3 db $file_to_analyze} res]} { | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | } if {![file readable $root_filename]} { puts stderr "File is not readable: $root_filename" exit 1 } if {[catch {sqlite3 db $file_to_analyze} res]} { puts stderr "Cannot open database $root_filename: $res" exit 1 } if {$bFreelistCheck || $bAll} { puts -nonewline "freelist-check: " flush stdout db eval BEGIN |
︙ | ︙ |
Changes to ext/rtree/README.
︙ | ︙ | |||
102 103 104 105 106 107 108 | and use it as a dynamically loadable SQLite extension. To do this using gcc on *nix: gcc -shared rtree.c -o libSqliteRtree.so You may need to add "-I" flags so that gcc can find sqlite3ext.h and sqlite3.h. The resulting shared lib, libSqliteRtree.so, may be | | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | and use it as a dynamically loadable SQLite extension. To do this using gcc on *nix: gcc -shared rtree.c -o libSqliteRtree.so You may need to add "-I" flags so that gcc can find sqlite3ext.h and sqlite3.h. The resulting shared lib, libSqliteRtree.so, may be loaded into sqlite in the same way as any other dynamically loadable extension. 3. REFERENCES [1] Antonin Guttman, "R-trees - A Dynamic Index Structure For Spatial Searching", University of California Berkeley, 1984. [2] Norbert Beckmann, Hans-Peter Kriegel, Ralf Schneider, Bernhard Seeger, "The R*-tree: An Efficient and Robust Access Method for Points and Rectangles", Universitaet Bremen, 1990. |
Changes to ext/rtree/geopoly.c.
︙ | ︙ | |||
757 758 759 760 761 762 763 | } /* ** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). ** Returns: ** | | | 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 | } /* ** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). ** Returns: ** ** +2 x0,y0 is on the line segment ** ** +1 x0,y0 is beneath line segment ** ** 0 x0,y0 is not on or beneath the line segment or the line segment ** is vertical and x0,y0 is not on the line segment ** ** The left-most coordinate min(x1,x2) is not considered to be part of |
︙ | ︙ | |||
860 861 862 863 864 865 866 | sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); } } sqlite3_free(p1); sqlite3_free(p2); } | | | 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 | sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); } } sqlite3_free(p1); sqlite3_free(p2); } /* Objects used by the overlap algorithm. */ typedef struct GeoEvent GeoEvent; typedef struct GeoSegment GeoSegment; typedef struct GeoOverlap GeoOverlap; struct GeoEvent { double x; /* X coordinate at which event occurs */ int eType; /* 0 for ADD, 1 for REMOVE */ GeoSegment *pSeg; /* The segment to be added or removed */ |
︙ | ︙ |
Changes to ext/rtree/rtree.c.
︙ | ︙ | |||
324 325 326 327 328 329 330 | #define RTREE_GE 0x44 /* D */ #define RTREE_GT 0x45 /* E */ #define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */ #define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */ /* Special operators available only on cursors. Needs to be consecutive ** with the normal values above, but must be less than RTREE_MATCH. These | | | 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | #define RTREE_GE 0x44 /* D */ #define RTREE_GT 0x45 /* E */ #define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */ #define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */ /* Special operators available only on cursors. Needs to be consecutive ** with the normal values above, but must be less than RTREE_MATCH. These ** are used in the cursor for constraints such as x=NULL (RTREE_FALSE) or ** x<'xyz' (RTREE_TRUE) */ #define RTREE_TRUE 0x3f /* ? */ #define RTREE_FALSE 0x40 /* @ */ /* ** An rtree structure node. */ |
︙ | ︙ | |||
2028 2029 2030 2031 2032 2033 2034 | pIdxInfo->estimatedCost = (double)6.0 * (double)nRow; pIdxInfo->estimatedRows = nRow; return rc; } /* | | | 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 | pIdxInfo->estimatedCost = (double)6.0 * (double)nRow; pIdxInfo->estimatedRows = nRow; return rc; } /* ** Return the N-dimensional volume of the cell stored in *p. */ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ RtreeDValue area = (RtreeDValue)1; assert( pRtree->nDim>=1 && pRtree->nDim<=5 ); #ifndef SQLITE_RTREE_INT_ONLY if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ switch( pRtree->nDim ){ |
︙ | ︙ | |||
4388 4389 4390 4391 4392 4393 4394 | return rc; } /* ** This routine deletes the RtreeGeomCallback object that was attached ** one of the SQL functions create by sqlite3_rtree_geometry_callback() ** or sqlite3_rtree_query_callback(). In other words, this routine is the | | | 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 | return rc; } /* ** This routine deletes the RtreeGeomCallback object that was attached ** one of the SQL functions create by sqlite3_rtree_geometry_callback() ** or sqlite3_rtree_query_callback(). In other words, this routine is the ** destructor for an RtreeGeomCallback object. This routine is called when ** the corresponding SQL function is deleted. */ static void rtreeFreeCallback(void *p){ RtreeGeomCallback *pInfo = (RtreeGeomCallback*)p; if( pInfo->xDestructor ) pInfo->xDestructor(pInfo->pContext); sqlite3_free(p); } |
︙ | ︙ |
Changes to ext/rtree/rtree4.test.
︙ | ︙ | |||
144 145 146 147 148 149 150 | lappend where mx$j>=$mn mn$j<=$mx } set where "WHERE [join $where { AND }]" do_test rtree4-$nDim.2.$i.3 { list $where [db eval "SELECT id FROM rx $where ORDER BY id"] } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] | | | | | | | | 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 | lappend where mx$j>=$mn mn$j<=$mx } set where "WHERE [join $where { AND }]" do_test rtree4-$nDim.2.$i.3 { list $where [db eval "SELECT id FROM rx $where ORDER BY id"] } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] # Do a contained-in query with surplus constraints at the beginning. # This should force a full-table scan on the rtree. # set where {} for {set j 0} {$j<$nDim} {incr j} { lappend where mn$j>-10000 mx$j<10000 } for {set j 0} {$j<$nDim} {incr j} { set mn [rand 10000] set mx [expr {$mn+[randincr 500]}] lappend where mn$j>=$mn mx$j<=$mx } set where "WHERE [join $where { AND }]" do_test rtree4-$nDim.2.$i.3 { list $where [db eval "SELECT id FROM rx $where ORDER BY id"] } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] # Do an overlaps query with surplus constraints at the beginning. # This should force a full-table scan on the rtree. # set where {} for {set j 0} {$j<$nDim} {incr j} { lappend where mn$j>=-10000 mx$j<=10000 } for {set j 0} {$j<$nDim} {incr j} { set mn [rand 10000] set mx [expr {$mn+[randincr 500]}] lappend where mx$j>$mn mn$j<$mx } set where "WHERE [join $where { AND }]" do_test rtree4-$nDim.2.$i.4 { list $where [db eval "SELECT id FROM rx $where ORDER BY id"] } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] # Do a contained-in query with surplus constraints at the end # set where {} for {set j 0} {$j<$nDim} {incr j} { set mn [rand 10000] set mx [expr {$mn+[randincr 500]}] lappend where mn$j>=$mn mx$j<$mx } for {set j [expr {$nDim-1}]} {$j>=0} {incr j -1} { lappend where mn$j>=-10000 mx$j<10000 } set where "WHERE [join $where { AND }]" do_test rtree4-$nDim.2.$i.5 { list $where [db eval "SELECT id FROM rx $where ORDER BY id"] } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] # Do an overlaps query with surplus constraints at the end # set where {} for {set j [expr {$nDim-1}]} {$j>=0} {incr j -1} { set mn [rand 10000] set mx [expr {$mn+[randincr 500]}] lappend where mx$j>$mn mn$j<=$mx } for {set j 0} {$j<$nDim} {incr j} { lappend where mx$j>-10000 mn$j<=10000 } set where "WHERE [join $where { AND }]" do_test rtree4-$nDim.2.$i.6 { list $where [db eval "SELECT id FROM rx $where ORDER BY id"] } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] # Do a contained-in query with surplus constraints where the # constraints appear in a random order. # set where {} for {set j 0} {$j<$nDim} {incr j} { set mn1 [rand 10000] set mn2 [expr {$mn1+[randincr 100]}] set mx1 [expr {$mn2+[randincr 400]}] set mx2 [expr {$mx1+[randincr 100]}] lappend where mn$j>=$mn1 mn$j>$mn2 mx$j<$mx1 mx$j<=$mx2 } set where "WHERE [join [scramble $where] { AND }]" do_test rtree4-$nDim.2.$i.7 { list $where [db eval "SELECT id FROM rx $where ORDER BY id"] } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] # Do an overlaps query with surplus constraints where the # constraints appear in a random order. # set where {} for {set j 0} {$j<$nDim} {incr j} { set mn1 [rand 10000] set mn2 [expr {$mn1+[randincr 100]}] set mx1 [expr {$mn2+[randincr 400]}] |
︙ | ︙ |
Changes to ext/rtree/rtree_util.tcl.
︙ | ︙ | |||
190 191 192 193 194 195 196 | set d [rtree_depth $db $zTab] rtree_nodetreedump $db $zTab "" $d 1 } proc do_rtree_integrity_test {tn tbl} { uplevel [list do_execsql_test $tn "SELECT rtreecheck('$tbl')" ok] } | < | 190 191 192 193 194 195 196 | set d [rtree_depth $db $zTab] rtree_nodetreedump $db $zTab "" $d 1 } proc do_rtree_integrity_test {tn tbl} { uplevel [list do_execsql_test $tn "SELECT rtreecheck('$tbl')" ok] } |
Changes to ext/rtree/rtreecirc.test.
︙ | ︙ | |||
59 60 61 62 63 64 65 | do_execsql_test 1.1.$tn.1 $schema do_catchsql_test 1.1.$tn.2 $sql {1 {no such table: main.rt}} db close } finish_test | < | 59 60 61 62 63 64 65 | do_execsql_test 1.1.$tn.1 $schema do_catchsql_test 1.1.$tn.2 $sql {1 {no such table: main.rt}} db close } finish_test |
Changes to ext/session/changesetfuzz1.test.
︙ | ︙ | |||
77 78 79 80 81 82 83 | forcecopy input.patchset-0 input.patchset } } } {} finish_test | < | 77 78 79 80 81 82 83 | forcecopy input.patchset-0 input.patchset } } } {} finish_test |
Changes to ext/session/sessionwor.test.
︙ | ︙ | |||
93 94 95 96 97 98 99 | DELETE FROM t1; } { {DELETE t1 0 X. {i 1 t four} {}} } } finish_test | < | 93 94 95 96 97 98 99 | DELETE FROM t1; } { {DELETE t1 0 X. {i 1 t four} {}} } } finish_test |
Changes to ext/session/sqlite3session.c.
︙ | ︙ | |||
1061 1062 1063 1064 1065 1066 1067 | sqlite3_finalize(pStmt); return rc; } /* ** This function is only called from within a pre-update handler for a ** write to table pTab, part of session pSession. If this is the first | | | 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 | sqlite3_finalize(pStmt); return rc; } /* ** This function is only called from within a pre-update handler for a ** write to table pTab, part of session pSession. If this is the first ** write to this table, initialize the SessionTable.nCol, azCol[] and ** abPK[] arrays accordingly. ** ** If an error occurs, an error code is stored in sqlite3_session.rc and ** non-zero returned. Or, if no error occurs but the table has no primary ** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to ** indicate that updates on this table should be ignored. SessionTable.abPK ** is set to NULL in this case. |
︙ | ︙ | |||
1982 1983 1984 1985 1986 1987 1988 | *zOut++ = '"'; p->nBuf = (int)((u8 *)zOut - p->aBuf); } } /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is | | | 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 | *zOut++ = '"'; p->nBuf = (int)((u8 *)zOut - p->aBuf); } } /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is ** called. Otherwise, it appends the serialized version of the value stored ** in column iCol of the row that SQL statement pStmt currently points ** to to the buffer. */ static void sessionAppendCol( SessionBuffer *p, /* Buffer to append to */ sqlite3_stmt *pStmt, /* Handle pointing to row containing value */ int iCol, /* Column to read value from */ |
︙ | ︙ | |||
2363 2364 2365 2366 2367 2368 2369 | int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut, /* First argument for xOutput */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ){ sqlite3 *db = pSession->db; /* Source database handle */ SessionTable *pTab; /* Used to iterate through attached tables */ | | | 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 | int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut, /* First argument for xOutput */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ){ sqlite3 *db = pSession->db; /* Source database handle */ SessionTable *pTab; /* Used to iterate through attached tables */ SessionBuffer buf = {0,0,0}; /* Buffer in which to accumulate changeset */ int rc; /* Return code */ assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0 ) ); /* Zero the output variables in case an error occurs. If this session ** object is already in the error state (sqlite3_session.rc != SQLITE_OK), ** this call will be a no-op. */ |
︙ | ︙ | |||
3779 3780 3781 3782 3783 3784 3785 | /* ** Iterator pIter must point to an SQLITE_INSERT entry. This function ** transfers new.* values from the current iterator entry to statement ** pStmt. The table being inserted into has nCol columns. ** ** New.* value $i from the iterator is bound to variable ($i+1) of ** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1) | | | 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 | /* ** Iterator pIter must point to an SQLITE_INSERT entry. This function ** transfers new.* values from the current iterator entry to statement ** pStmt. The table being inserted into has nCol columns. ** ** New.* value $i from the iterator is bound to variable ($i+1) of ** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1) ** are transferred to the statement. Otherwise, if abPK is not NULL, it points ** to an array nCol elements in size. In this case only those values for ** which abPK[$i] is true are read from the iterator and bound to the ** statement. ** ** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK. */ static int sessionBindRow( |
︙ | ︙ | |||
3824 3825 3826 3827 3828 3829 3830 | /* ** SQL statement pSelect is as generated by the sessionSelectRow() function. ** This function binds the primary key values from the change that changeset ** iterator pIter points to to the SELECT and attempts to seek to the table ** entry. If a row is found, the SELECT statement left pointing at the row ** and SQLITE_ROW is returned. Otherwise, if no row is found and no error | | | | 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 | /* ** SQL statement pSelect is as generated by the sessionSelectRow() function. ** This function binds the primary key values from the change that changeset ** iterator pIter points to to the SELECT and attempts to seek to the table ** entry. If a row is found, the SELECT statement left pointing at the row ** and SQLITE_ROW is returned. Otherwise, if no row is found and no error ** has occurred, the statement is reset and SQLITE_OK is returned. If an ** error occurs, the statement is reset and an SQLite error code is returned. ** ** If this function returns SQLITE_ROW, the caller must eventually reset() ** statement pSelect. If any other value is returned, the statement does ** not require a reset(). ** ** If the iterator currently points to an INSERT record, bind values from the ** new.* record to the SELECT statement. Or, if it points to a DELETE or ** UPDATE, bind values from the old.* record. */ static int sessionSeekToRow( sqlite3 *db, /* Database handle */ sqlite3_changeset_iter *pIter, /* Changeset iterator */ u8 *abPK, /* Primary key flags array */ sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */ ){ int rc; /* Return code */ int nCol; /* Number of columns in table */ int op; /* Changeset operation (SQLITE_UPDATE etc.) */ const char *zDummy; /* Unused */ sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); rc = sessionBindRow(pIter, op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old, nCol, abPK, pSelect ); |
︙ | ︙ |
Changes to ext/userauth/sqlite3userauth.h.
︙ | ︙ | |||
31 32 33 34 35 36 37 | ** appropriate username and password prior to enable read and write ** access to the database. ** ** Return SQLITE_OK on success or SQLITE_ERROR if the username/password ** combination is incorrect or unknown. ** ** If the SQLITE_USER table is not present in the database file, then | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | ** appropriate username and password prior to enable read and write ** access to the database. ** ** Return SQLITE_OK on success or SQLITE_ERROR if the username/password ** combination is incorrect or unknown. ** ** If the SQLITE_USER table is not present in the database file, then ** this interface is a harmless no-op returning SQLITE_OK. */ int sqlite3_user_authenticate( sqlite3 *db, /* The database connection */ const char *zUsername, /* Username */ const char *aPW, /* Password or credentials */ int nPW /* Number of bytes in aPW[] */ ); |
︙ | ︙ |
Changes to ext/userauth/user-auth.txt.
︙ | ︙ | |||
150 151 152 153 154 155 156 | sqlite_user.pw == sqlite_crypt(X, sqlite_user.pw) To compute an appropriate sqlite_user.pw value from a new or modified password X, sqlite_crypt(X,NULL) is run. A new random salt is selected when the second argument is NULL. | | | | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | sqlite_user.pw == sqlite_crypt(X, sqlite_user.pw) To compute an appropriate sqlite_user.pw value from a new or modified password X, sqlite_crypt(X,NULL) is run. A new random salt is selected when the second argument is NULL. The built-in version of of sqlite_crypt() uses a simple Caesar-cypher which prevents passwords from being revealed by searching the raw database for ASCII text, but is otherwise trivially broken. For better password security, the database should be encrypted using the SQLite Encryption Extension or similar technology. Or, the application can use the sqlite3_create_function() interface to provide an alternative implementation of sqlite_crypt() that computes a stronger password hash, perhaps using a cryptographic hash function like SHA1. |
Changes to ext/userauth/userauth.c.
︙ | ︙ | |||
184 185 186 187 188 189 190 | ** appropriate username and password prior to enable read and write ** access to the database. ** ** Return SQLITE_OK on success or SQLITE_ERROR if the username/password ** combination is incorrect or unknown. ** ** If the SQLITE_USER table is not present in the database file, then | | | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | ** appropriate username and password prior to enable read and write ** access to the database. ** ** Return SQLITE_OK on success or SQLITE_ERROR if the username/password ** combination is incorrect or unknown. ** ** If the SQLITE_USER table is not present in the database file, then ** this interface is a harmless no-op returning SQLITE_OK. */ int sqlite3_user_authenticate( sqlite3 *db, /* The database connection */ const char *zUsername, /* Username */ const char *zPW, /* Password or credentials */ int nPW /* Number of bytes in aPW[] */ ){ |
︙ | ︙ |
Changes to ltmain.sh.
︙ | ︙ | |||
2432 2433 2434 2435 2436 2437 2438 | const char *name; void *address; } lt_dlsymlist; " case $host in *cygwin* | *mingw* | *cegcc* ) $ECHO >> "$output_objdir/$my_dlsyms" "\ | | | 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 | const char *name; void *address; } lt_dlsymlist; " case $host in *cygwin* | *mingw* | *cegcc* ) $ECHO >> "$output_objdir/$my_dlsyms" "\ /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */" lt_dlsym_const= ;; *osf5*) echo >> "$output_objdir/$my_dlsyms" "\ /* This system does not cope well with relocations in const data */" lt_dlsym_const= ;; |
︙ | ︙ | |||
3536 3537 3538 3539 3540 3541 3542 | lt_fatal ("%s missing required argument", env_append_opt); continue; } if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0) { /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX namespace, but it is not one of the ones we know about and | | | 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 | lt_fatal ("%s missing required argument", env_append_opt); continue; } if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0) { /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX namespace, but it is not one of the ones we know about and have already dealt with, above (including dump-script), then report an error. Otherwise, targets might begin to believe they are allowed to use options in the LTWRAPPER_OPTION_PREFIX namespace. The first time any user complains about this, we'll need to make LTWRAPPER_OPTION_PREFIX a configure-time option or a configure.ac-settable value. */ lt_fatal ("Unrecognized option in %s namespace: '%s'", |
︙ | ︙ | |||
8454 8455 8456 8457 8458 8459 8460 | # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 | < | 8454 8455 8456 8457 8458 8459 8460 | # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 |
Changes to main.mk.
︙ | ︙ | |||
1080 1081 1082 1083 1084 1085 1086 | # This target will fail if the SQLite amalgamation contains any exported # symbols that do not begin with "sqlite3_". It is run as part of the # releasetest.tcl script. # checksymbols: sqlite3.o nm -g --defined-only sqlite3.o | grep -v " sqlite3_" ; test $$? -ne 0 | | | 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 | # This target will fail if the SQLite amalgamation contains any exported # symbols that do not begin with "sqlite3_". It is run as part of the # releasetest.tcl script. # checksymbols: sqlite3.o nm -g --defined-only sqlite3.o | grep -v " sqlite3_" ; test $$? -ne 0 # Build the amalgamation-autoconf package. The amalagmation-tarball target builds # a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz. # The snapshot-tarball target builds a tarball named by the SHA1 hash # amalgamation-tarball: sqlite3.c sqlite3rc.h TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal snapshot-tarball: sqlite3.c sqlite3rc.h |
︙ | ︙ |
Changes to src/alter.c.
︙ | ︙ | |||
941 942 943 944 945 946 947 | for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext); *pp = pBest->pNext; return pBest; } /* | | | 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 | for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext); *pp = pBest->pNext; return pBest; } /* ** An error occurred while parsing or otherwise processing a database ** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an ** ALTER TABLE RENAME COLUMN program. The error message emitted by the ** sub-routine is currently stored in pParse->zErrMsg. This function ** adds context to the error message and then stores it in pCtx. */ static void renameColumnParseError( sqlite3_context *pCtx, |
︙ | ︙ |
Changes to src/auth.c.
︙ | ︙ | |||
201 202 203 204 205 206 207 | const char *zArg1, const char *zArg2, const char *zArg3 ){ sqlite3 *db = pParse->db; int rc; | | | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | const char *zArg1, const char *zArg2, const char *zArg3 ){ sqlite3 *db = pParse->db; int rc; /* Don't do any authorization checks if the database is initializing ** or if the parser is being invoked from within sqlite3_declare_vtab. */ assert( !IN_RENAME_OBJECT || db->xAuth==0 ); if( db->init.busy || IN_SPECIAL_PARSE ){ return SQLITE_OK; } |
︙ | ︙ |
Changes to src/bitvec.c.
︙ | ︙ | |||
184 185 186 187 188 189 190 | if( p->iSize<=BITVEC_NBIT ){ p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1)); return SQLITE_OK; } h = BITVEC_HASH(i++); /* if there wasn't a hash collision, and this doesn't */ /* completely fill the hash, then just add it without */ | | | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | if( p->iSize<=BITVEC_NBIT ){ p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1)); return SQLITE_OK; } h = BITVEC_HASH(i++); /* if there wasn't a hash collision, and this doesn't */ /* completely fill the hash, then just add it without */ /* worrying about sub-dividing and re-hashing. */ if( !p->u.aHash[h] ){ if (p->nSet<(BITVEC_NINT-1)) { goto bitvec_set_end; } else { goto bitvec_set_rehash; } } |
︙ | ︙ |
Changes to src/btmutex.c.
︙ | ︙ | |||
174 175 176 177 178 179 180 | ** connection. This is needed (for example) prior to parsing ** a statement since we will be comparing table and column names ** against all schemas and we do not want those schemas being ** reset out from under us. ** ** There is a corresponding leave-all procedures. ** | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | ** connection. This is needed (for example) prior to parsing ** a statement since we will be comparing table and column names ** against all schemas and we do not want those schemas being ** reset out from under us. ** ** There is a corresponding leave-all procedures. ** ** Enter the mutexes in ascending order by BtShared pointer address ** to avoid the possibility of deadlock when two threads with ** two or more btrees in common both try to lock all their btrees ** at the same instant. */ static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){ int i; int skipOk = 1; |
︙ | ︙ |
Changes to src/btree.c.
︙ | ︙ | |||
480 481 482 483 484 485 486 | */ #ifdef SQLITE_DEBUG static int cursorHoldsMutex(BtCursor *p){ return sqlite3_mutex_held(p->pBt->mutex); } /* Verify that the cursor and the BtShared agree about what is the current | | | 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | */ #ifdef SQLITE_DEBUG static int cursorHoldsMutex(BtCursor *p){ return sqlite3_mutex_held(p->pBt->mutex); } /* Verify that the cursor and the BtShared agree about what is the current ** database connection. This is important in shared-cache mode. If the database ** connection pointers get out-of-sync, it is possible for routines like ** btreeInitPage() to reference an stale connection pointer that references a ** a connection that has already closed. This routine is used inside assert() ** statements only and for the purpose of double-checking that the btree code ** does keep the database connection pointers up-to-date. */ static int cursorOwnsBtShared(BtCursor *p){ |
︙ | ︙ | |||
900 901 902 903 904 905 906 | /* ** This routine restores a cursor back to its original position after it ** has been moved by some outside activity (such as a btree rebalance or ** a row having been deleted out from under the cursor). ** ** On success, the *pDifferentRow parameter is false if the cursor is left | | | 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 | /* ** This routine restores a cursor back to its original position after it ** has been moved by some outside activity (such as a btree rebalance or ** a row having been deleted out from under the cursor). ** ** On success, the *pDifferentRow parameter is false if the cursor is left ** pointing at exactly the same row. *pDifferentRow is the row the cursor ** was pointing to has been deleted, forcing the cursor to point to some ** nearby row. ** ** This routine should only be called for a cursor that just returned ** TRUE from sqlite3BtreeCursorHasMoved(). */ int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ |
︙ | ︙ | |||
1697 1698 1699 1700 1701 1702 1703 | ** The first byte of the new free block is pPage->aData[iStart] ** and the size of the block is iSize bytes. ** ** Adjacent freeblocks are coalesced. ** ** Even though the freeblock list was checked by btreeComputeFreeSpace(), ** that routine will not detect overlap between cells or freeblocks. Nor | | | 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 | ** The first byte of the new free block is pPage->aData[iStart] ** and the size of the block is iSize bytes. ** ** Adjacent freeblocks are coalesced. ** ** Even though the freeblock list was checked by btreeComputeFreeSpace(), ** that routine will not detect overlap between cells or freeblocks. Nor ** does it detect cells or freeblocks that encroach into the reserved bytes ** at the end of the page. So do additional corruption checks inside this ** routine and return SQLITE_CORRUPT if any problems are found. */ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ u16 iPtr; /* Address of ptr to next freeblock */ u16 iFreeBlk; /* Address of the next freeblock */ u8 hdr; /* Page header size. 0 or 100 */ |
︙ | ︙ | |||
2244 2245 2246 2247 2248 2249 2250 | /* ** Get an unused page. ** ** This works just like btreeGetPage() with the addition: ** ** * If the page is already in use for some other purpose, immediately | | | 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 | /* ** Get an unused page. ** ** This works just like btreeGetPage() with the addition: ** ** * If the page is already in use for some other purpose, immediately ** release it and return an SQLITE_CORRUPT error. ** * Make sure the isInit flag is clear */ static int btreeGetUnusedPage( BtShared *pBt, /* The btree */ Pgno pgno, /* Number of the page to fetch */ MemPage **ppPage, /* Return the page in this parameter */ int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */ |
︙ | ︙ | |||
2674 2675 2676 2677 2678 2679 2680 | /* One of the uses of pBt->pTmpSpace is to format cells before ** inserting them into a leaf page (function fillInCell()). If ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes ** by the various routines that manipulate binary cells. Which ** can mean that fillInCell() only initializes the first 2 or 3 ** bytes of pTmpSpace, but that the first 4 bytes are copied from ** it into a database page. This is not actually a problem, but it | | | 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 | /* One of the uses of pBt->pTmpSpace is to format cells before ** inserting them into a leaf page (function fillInCell()). If ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes ** by the various routines that manipulate binary cells. Which ** can mean that fillInCell() only initializes the first 2 or 3 ** bytes of pTmpSpace, but that the first 4 bytes are copied from ** it into a database page. This is not actually a problem, but it ** does cause a valgrind error when the 1 or 2 bytes of uninitialized ** data is passed to system call write(). So to avoid this error, ** zero the first 4 bytes of temp space here. ** ** Also: Provide four bytes of initialized space before the ** beginning of pTmpSpace as an area available to prepend the ** left-child pointer to the beginning of a cell. */ |
︙ | ︙ | |||
2906 2907 2908 2909 2910 2911 2912 | assert( sqlite3_mutex_held(p->pBt->mutex) ); n = p->pBt->pageSize - p->pBt->usableSize; return n; } /* ** Return the number of bytes of space at the end of every page that | | | 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 | assert( sqlite3_mutex_held(p->pBt->mutex) ); n = p->pBt->pageSize - p->pBt->usableSize; return n; } /* ** Return the number of bytes of space at the end of every page that ** are intentionally left unused. This is the "reserved" space that is ** sometimes used by extensions. ** ** The value returned is the larger of the current reserve size and ** the latest reserve size requested by SQLITE_FILECTRL_RESERVE_BYTES. ** The amount of reserve can only grow - never shrink. */ int sqlite3BtreeGetRequestedReserve(Btree *p){ |
︙ | ︙ | |||
4628 4629 4630 4631 4632 4633 4634 | ** Return an upper bound on the size of any record for the table ** that the cursor is pointing into. ** ** This is an optimization. Everything will still work if this ** routine always returns 2147483647 (which is the largest record ** that SQLite can handle) or more. But returning a smaller value might ** prevent large memory allocations when trying to interpret a | | | 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 | ** Return an upper bound on the size of any record for the table ** that the cursor is pointing into. ** ** This is an optimization. Everything will still work if this ** routine always returns 2147483647 (which is the largest record ** that SQLite can handle) or more. But returning a smaller value might ** prevent large memory allocations when trying to interpret a ** corrupt database. ** ** The current implementation merely returns the size of the underlying ** database file. */ sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); |
︙ | ︙ | |||
5437 5438 5439 5440 5441 5442 5443 | if( (pCur->curFlags & BTCF_AtLast)!=0 ){ *pRes = -1; return SQLITE_OK; } /* If the requested key is one more than the previous key, then ** try to get there using sqlite3BtreeNext() rather than a full ** binary search. This is an optimization only. The correct answer | | | 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 | if( (pCur->curFlags & BTCF_AtLast)!=0 ){ *pRes = -1; return SQLITE_OK; } /* If the requested key is one more than the previous key, then ** try to get there using sqlite3BtreeNext() rather than a full ** binary search. This is an optimization only. The correct answer ** is still obtained without this case, only a little more slowly */ if( pCur->info.nKey+1==intKey ){ *pRes = 0; rc = sqlite3BtreeNext(pCur, 0); if( rc==SQLITE_OK ){ getCellInfo(pCur); if( pCur->info.nKey==intKey ){ return SQLITE_OK; |
︙ | ︙ | |||
7317 7318 7319 7320 7321 7322 7323 | } pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell; /* If this is an auto-vacuum database, update the pointer map ** with entries for the new page, and any pointer from the ** cell on the page to an overflow page. If either of these ** operations fails, the return code is set, but the contents | | | 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 | } pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell; /* If this is an auto-vacuum database, update the pointer map ** with entries for the new page, and any pointer from the ** cell on the page to an overflow page. If either of these ** operations fails, the return code is set, but the contents ** of the parent page are still manipulated by the code below. ** That is Ok, at this point the parent page is guaranteed to ** be marked as dirty. Returning an error code will cause a ** rollback, undoing any changes made to the parent page. */ if( ISAUTOVACUUM ){ ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc); if( szCell>pNew->minLocal ){ |
︙ | ︙ | |||
7908 7909 7910 7911 7912 7913 7914 | szNew[i-1] = szLeft; if( cntNew[i-1] <= (i>1 ? cntNew[i-2] : 0) ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } } | | | 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 | szNew[i-1] = szLeft; if( cntNew[i-1] <= (i>1 ? cntNew[i-2] : 0) ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } } /* Sanity check: For a non-corrupt database file one of the following ** must be true: ** (1) We found one or more cells (cntNew[0])>0), or ** (2) pPage is a virtual root page. A virtual root page is when ** the real root page is page 1 and we are the only child of ** that page. */ assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB); |
︙ | ︙ | |||
8508 8509 8510 8511 8512 8513 8514 | u8 *pDest, /* Pointer to the place to start writing */ const BtreePayload *pX, /* Source of data to write */ int iOffset, /* Offset of first byte to write */ int iAmt /* Number of bytes to be written */ ){ int nData = pX->nData - iOffset; if( nData<=0 ){ | | | 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 | u8 *pDest, /* Pointer to the place to start writing */ const BtreePayload *pX, /* Source of data to write */ int iOffset, /* Offset of first byte to write */ int iAmt /* Number of bytes to be written */ ){ int nData = pX->nData - iOffset; if( nData<=0 ){ /* Overwriting with zeros */ int i; for(i=0; i<iAmt && pDest[i]==0; i++){} if( i<iAmt ){ int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; memset(pDest + i, 0, iAmt - i); } |
︙ | ︙ |
Changes to src/btree.h.
︙ | ︙ | |||
171 172 173 174 175 176 177 | ** ** The design of the _RANGE hint is aid b-tree implementations that try ** to prefetch content from remote machines - to provide those ** implementations with limits on what needs to be prefetched and thereby ** reduce network bandwidth. ** ** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by | | | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | ** ** The design of the _RANGE hint is aid b-tree implementations that try ** to prefetch content from remote machines - to provide those ** implementations with limits on what needs to be prefetched and thereby ** reduce network bandwidth. ** ** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by ** standard SQLite. The other hints are provided for extensions that use ** the SQLite parser and code generator but substitute their own storage ** engine. */ #define BTREE_HINT_RANGE 0 /* Range constraints on queries */ /* ** Values that may be OR'd together to form the argument to the |
︙ | ︙ |
Changes to src/btreeInt.h.
︙ | ︙ | |||
259 260 261 262 263 264 265 | #define PTF_LEAF 0x08 /* ** An instance of this object stores information about each a single database ** page that has been loaded into memory. The information in this object ** is derived from the raw on-disk page content. ** | | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | #define PTF_LEAF 0x08 /* ** An instance of this object stores information about each a single database ** page that has been loaded into memory. The information in this object ** is derived from the raw on-disk page content. ** ** As each database page is loaded into memory, the pager allocates an ** instance of this object and zeros the first 8 bytes. (This is the ** "extra" information associated with each page of the pager.) ** ** Access to all fields of this structure is controlled by the mutex ** stored in MemPage.pBt->mutex. */ struct MemPage { |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
1441 1442 1443 1444 1445 1446 1447 | ** This routine is called by the parser while in the middle of ** parsing a CREATE TABLE statement. */ void sqlite3AddDefaultValue( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The parsed expression of the default value */ const char *zStart, /* Start of the default value text */ | | | 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 | ** This routine is called by the parser while in the middle of ** parsing a CREATE TABLE statement. */ void sqlite3AddDefaultValue( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The parsed expression of the default value */ const char *zStart, /* Start of the default value text */ const char *zEnd /* First character past end of default value text */ ){ Table *p; Column *pCol; sqlite3 *db = pParse->db; p = pParse->pNewTable; if( p!=0 ){ int isInit = db->init.busy && db->init.iDb!=1; |
︙ | ︙ | |||
3537 3538 3539 3540 3541 3542 3543 | iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); if( iDb<0 ) goto exit_create_index; assert( pName && pName->z ); #ifndef SQLITE_OMIT_TEMPDB /* If the index name was unqualified, check if the table ** is a temp table. If so, set the database to 1. Do not do this | | | 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 | iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); if( iDb<0 ) goto exit_create_index; assert( pName && pName->z ); #ifndef SQLITE_OMIT_TEMPDB /* If the index name was unqualified, check if the table ** is a temp table. If so, set the database to 1. Do not do this ** if initialiing a database schema. */ if( !db->init.busy ){ pTab = sqlite3SrcListLookup(pParse, pTblName); if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ iDb = 1; } } |
︙ | ︙ |
Changes to src/delete.c.
︙ | ︙ | |||
145 146 147 148 149 150 151 | ExprList *pOrderBy, /* The ORDER BY clause. May be null */ Expr *pLimit, /* The LIMIT clause. May be null */ char *zStmtType /* Either DELETE or UPDATE. For err msgs. */ ){ sqlite3 *db = pParse->db; Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | ExprList *pOrderBy, /* The ORDER BY clause. May be null */ Expr *pLimit, /* The LIMIT clause. May be null */ char *zStmtType /* Either DELETE or UPDATE. For err msgs. */ ){ sqlite3 *db = pParse->db; Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ ExprList *pEList = NULL; /* Expressions containing only pSelectRowid */ SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ Select *pSelect = NULL; /* Complete SELECT tree */ Table *pTab; /* Check that there isn't an ORDER BY without a LIMIT clause. */ if( pOrderBy && pLimit==0 ) { |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
216 217 218 219 220 221 222 | } return pColl; } /* ** Return the collation sequence for the expression pExpr. If ** there is no defined collating sequence, return a pointer to the | | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | } return pColl; } /* ** Return the collation sequence for the expression pExpr. If ** there is no defined collating sequence, return a pointer to the ** default collation sequence. ** ** See also: sqlite3ExprCollSeq() ** ** The sqlite3ExprCollSeq() routine works the same except that it ** returns NULL if there is no defined collation. */ CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){ |
︙ | ︙ | |||
2451 2452 2453 2454 2455 2456 2457 | ** ** The returned value of this function indicates the b-tree type, as follows: ** ** IN_INDEX_ROWID - The cursor was opened on a database table. ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. ** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. ** IN_INDEX_EPH - The cursor was opened on a specially created and | | | 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 | ** ** The returned value of this function indicates the b-tree type, as follows: ** ** IN_INDEX_ROWID - The cursor was opened on a database table. ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. ** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. ** IN_INDEX_EPH - The cursor was opened on a specially created and ** populated ephemeral table. ** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be ** implemented as a sequence of comparisons. ** ** An existing b-tree might be used if the RHS expression pX is a simple ** subquery such as: ** ** SELECT <column1>, <column2>... FROM <table> |
︙ | ︙ | |||
2473 2474 2475 2476 2477 2478 2479 | ** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains ** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast ** membership test. When the IN_INDEX_LOOP bit is set, the IN index will ** be used to loop over all values of the RHS of the IN operator. ** ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate ** through the set members) then the b-tree must not contain duplicates. | | | | 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 | ** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains ** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast ** membership test. When the IN_INDEX_LOOP bit is set, the IN index will ** be used to loop over all values of the RHS of the IN operator. ** ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate ** through the set members) then the b-tree must not contain duplicates. ** An ephemeral table will be created unless the selected columns are guaranteed ** to be unique - either because it is an INTEGER PRIMARY KEY or due to ** a UNIQUE constraint or index. ** ** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used ** for fast set membership tests) then an ephemeral table must ** be used unless <columns> is a single INTEGER PRIMARY KEY column or an ** index can be found with the specified <columns> as its left-most. ** ** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and ** if the RHS of the IN operator is a list (not a subquery) then this ** routine might decide that creating an ephemeral b-tree for membership ** testing is too expensive and return IN_INDEX_NOOP. In that case, the |
︙ | ︙ | |||
2809 2810 2811 2812 2813 2814 2815 | ** in the RHS of an IN operator. The IN operator can be in either of two ** forms: ** ** x IN (4,5,11) -- IN operator with list on right-hand side ** x IN (SELECT a FROM b) -- IN operator with subquery on the right ** ** The pExpr parameter is the IN operator. The cursor number for the | | | 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 | ** in the RHS of an IN operator. The IN operator can be in either of two ** forms: ** ** x IN (4,5,11) -- IN operator with list on right-hand side ** x IN (SELECT a FROM b) -- IN operator with subquery on the right ** ** The pExpr parameter is the IN operator. The cursor number for the ** constructed ephemeral table is returned. The first time the ephemeral ** table is computed, the cursor number is also stored in pExpr->iTable, ** however the cursor number returned might not be the same, as it might ** have been duplicated using OP_OpenDup. ** ** If the LHS expression ("x" in the examples) is a column value, or ** the SELECT statement returns a column value, then the affinity of that ** column is used to build the index keys. If both 'x' and the |
︙ | ︙ | |||
3624 3625 3626 3627 3628 3629 3630 | p->op = TK_REGISTER; p->iTable = iReg; ExprClearProperty(p, EP_Skip); } /* ** Evaluate an expression (either a vector or a scalar expression) and store | | | 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 | p->op = TK_REGISTER; p->iTable = iReg; ExprClearProperty(p, EP_Skip); } /* ** Evaluate an expression (either a vector or a scalar expression) and store ** the result in contiguous temporary registers. Return the index of ** the first register used to store the result. ** ** If the returned result register is a temporary scalar, then also write ** that register number into *piFreeable. If the returned result register ** is not a temporary or if the expression is a vector set *piFreeable ** to 0. */ |
︙ | ︙ | |||
3839 3840 3841 3842 3843 3844 3845 | } case TK_COLUMN: { int iTab = pExpr->iTable; int iReg; if( ExprHasProperty(pExpr, EP_FixedCol) ){ /* This COLUMN expression is really a constant due to WHERE clause ** constraints, and that constant is coded by the pExpr->pLeft | | | 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 | } case TK_COLUMN: { int iTab = pExpr->iTable; int iReg; if( ExprHasProperty(pExpr, EP_FixedCol) ){ /* This COLUMN expression is really a constant due to WHERE clause ** constraints, and that constant is coded by the pExpr->pLeft ** expression. However, make sure the constant has the correct ** datatype by applying the Affinity of the table column to the ** constant. */ int aff; iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); if( pExpr->y.pTab ){ aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); |
︙ | ︙ | |||
5423 5424 5425 5426 5427 5428 5429 | ** ** pE1: x==5 pE2: x==5 Result: true ** pE1: x>0 pE2: x==5 Result: false ** pE1: x=21 pE2: x=21 OR y=43 Result: true ** pE1: x!=123 pE2: x IS NOT NULL Result: true ** pE1: x!=?1 pE2: x IS NOT NULL Result: true ** pE1: x IS NULL pE2: x IS NOT NULL Result: false | | | 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 | ** ** pE1: x==5 pE2: x==5 Result: true ** pE1: x>0 pE2: x==5 Result: false ** pE1: x=21 pE2: x=21 OR y=43 Result: true ** pE1: x!=123 pE2: x IS NOT NULL Result: true ** pE1: x!=?1 pE2: x IS NOT NULL Result: true ** pE1: x IS NULL pE2: x IS NOT NULL Result: false ** pE1: x IS ?2 pE2: x IS NOT NULL Result: false ** ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has ** Expr.iTable<0 then assume a table number given by iTab. ** ** If pParse is not NULL, then the values of bound variables in pE1 are ** compared against literal values in pE2 and pParse->pVdbe->expmask is ** modified to record which bound variables are referenced. If pParse |
︙ | ︙ |
Changes to src/func.c.
︙ | ︙ | |||
609 610 611 612 613 614 615 | u8 matchOne; /* "?" or "_" */ u8 matchSet; /* "[" or 0 */ u8 noCase; /* true to ignore case differences */ }; /* ** For LIKE and GLOB matching on EBCDIC machines, assume that every | | | 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 | u8 matchOne; /* "?" or "_" */ u8 matchSet; /* "[" or 0 */ u8 noCase; /* true to ignore case differences */ }; /* ** For LIKE and GLOB matching on EBCDIC machines, assume that every ** character is exactly one byte in size. Also, provide the Utf8Read() ** macro for fast reading of the next character in the common case where ** the next character is ASCII. */ #if defined(SQLITE_EBCDIC) # define sqlite3Utf8Read(A) (*((*A)++)) # define Utf8Read(A) (*(A++)) #else |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
1341 1342 1343 1344 1345 1346 1347 | */ #define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */ #define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */ /* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). * Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this ** expression node references any of the | | | 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 | */ #define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */ #define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */ /* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). * Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this ** expression node references any of the ** columns that are being modified by an UPDATE statement. */ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_COLUMN ){ assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 ); if( pExpr->iColumn>=0 ){ if( pWalker->u.aiCol[pExpr->iColumn]>=0 ){ pWalker->eCode |= CKCNSTRNT_COLUMN; |
︙ | ︙ | |||
1500 1501 1502 1503 1504 1505 1506 | u8 pkChng, /* Non-zero if the rowid or PRIMARY KEY changed */ u8 overrideError, /* Override onError to this if not OE_Default */ int ignoreDest, /* Jump to this label on an OE_Ignore resolution */ int *pbMayReplace, /* OUT: Set to true if constraint may cause a replace */ int *aiChng, /* column i is unchanged if aiChng[i]<0 */ Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */ ){ | | | 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 | u8 pkChng, /* Non-zero if the rowid or PRIMARY KEY changed */ u8 overrideError, /* Override onError to this if not OE_Default */ int ignoreDest, /* Jump to this label on an OE_Ignore resolution */ int *pbMayReplace, /* OUT: Set to true if constraint may cause a replace */ int *aiChng, /* column i is unchanged if aiChng[i]<0 */ Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */ ){ Vdbe *v; /* VDBE under construction */ Index *pIdx; /* Pointer to one of the indices */ Index *pPk = 0; /* The PRIMARY KEY index */ sqlite3 *db; /* Database connection */ int i; /* loop counter */ int ix; /* Index loop counter */ int nCol; /* Number of columns */ int onError; /* Conflict resolution strategy */ |
︙ | ︙ | |||
1810 1811 1812 1813 1814 1815 1816 | /* If the response to a rowid conflict is REPLACE but the response ** to some other UNIQUE constraint is FAIL or IGNORE, then we need ** to defer the running of the rowid conflict checking until after ** the UNIQUE constraints have run. */ if( onError==OE_Replace /* IPK rule is REPLACE */ | | | 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 | /* If the response to a rowid conflict is REPLACE but the response ** to some other UNIQUE constraint is FAIL or IGNORE, then we need ** to defer the running of the rowid conflict checking until after ** the UNIQUE constraints have run. */ if( onError==OE_Replace /* IPK rule is REPLACE */ && onError!=overrideError /* Rules for other constraints are different */ && pTab->pIndex /* There exist other constraints */ ){ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; VdbeComment((v, "defer IPK REPLACE until last")); } if( isUpdate ){ |
︙ | ︙ | |||
1921 1922 1923 1924 1925 1926 1927 | ** index and making sure that duplicate entries do not already exist. ** Compute the revised record entries for indices as we go. ** ** This loop also handles the case of the PRIMARY KEY index for a ** WITHOUT ROWID table. */ for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){ | | | 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 | ** index and making sure that duplicate entries do not already exist. ** Compute the revised record entries for indices as we go. ** ** This loop also handles the case of the PRIMARY KEY index for a ** WITHOUT ROWID table. */ for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){ int regIdx; /* Range of registers hold content for pIdx */ int regR; /* Range of registers holding conflicting PK */ int iThisCur; /* Cursor for this UNIQUE index */ int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ int addrConflictCk; /* First opcode in the conflict check logic */ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ if( pUpIdx==pIdx ){ |
︙ | ︙ | |||
2714 2715 2716 2717 2718 2719 2720 | } #ifndef SQLITE_OMIT_CHECK if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } #endif #ifndef SQLITE_OMIT_FOREIGN_KEY | | | 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 | } #ifndef SQLITE_OMIT_CHECK if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } #endif #ifndef SQLITE_OMIT_FOREIGN_KEY /* Disallow the transfer optimization if the destination table contains ** any foreign key constraints. This is more restrictive than necessary. ** But the main beneficiary of the transfer optimization is the VACUUM ** command, and the VACUUM command disables foreign key constraints. So ** the extra complication to make this rule less restrictive is probably ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] */ if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){ |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
3167 3168 3169 3170 3171 3172 3173 | ** undefined on on ** 3 on on ** 2 on off ** 1 off on ** 0 off off ** ** Legacy behavior is 3 (double-quoted string literals are allowed anywhere) | | | 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 | ** undefined on on ** 3 on on ** 2 on off ** 1 off on ** 0 off off ** ** Legacy behavior is 3 (double-quoted string literals are allowed anywhere) ** and so that is the default. But developers are encouraged to use ** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible. */ #if !defined(SQLITE_DQS) # define SQLITE_DQS 3 #endif #if (SQLITE_DQS&1)==1 | SQLITE_DqsDML |
︙ | ︙ | |||
3680 3681 3682 3683 3684 3685 3686 | if( !pTab || pTab->pSelect ){ pTab = 0; goto error_out; } /* Find the column for which info is requested */ if( zColumnName==0 ){ | | | 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 | if( !pTab || pTab->pSelect ){ pTab = 0; goto error_out; } /* Find the column for which info is requested */ if( zColumnName==0 ){ /* Query for existence of table only */ }else{ for(iCol=0; iCol<pTab->nCol; iCol++){ pCol = &pTab->aCol[iCol]; if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){ break; } } |
︙ | ︙ | |||
4445 4446 4447 4448 4449 4450 4451 | sqlite3_mutex_leave(db->mutex); #endif /* SQLITE_OMIT_WAL */ return rc; } /* | | | 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 | sqlite3_mutex_leave(db->mutex); #endif /* SQLITE_OMIT_WAL */ return rc; } /* ** Open a read-transaction on the snapshot identified by pSnapshot. */ int sqlite3_snapshot_open( sqlite3 *db, const char *zDb, sqlite3_snapshot *pSnapshot ){ int rc = SQLITE_ERROR; |
︙ | ︙ |
Changes to src/mem1.c.
︙ | ︙ | |||
152 153 154 155 156 157 158 | } /* ** Like free() but works for allocations obtained from sqlite3MemMalloc() ** or sqlite3MemRealloc(). ** ** For this low-level routine, we already know that pPrior!=0 since | | | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | } /* ** Like free() but works for allocations obtained from sqlite3MemMalloc() ** or sqlite3MemRealloc(). ** ** For this low-level routine, we already know that pPrior!=0 since ** cases where pPrior==0 will have been intercepted and dealt with ** by higher-level routines. */ static void sqlite3MemFree(void *pPrior){ #ifdef SQLITE_MALLOCSIZE SQLITE_FREE(pPrior); #else sqlite3_int64 *p = (sqlite3_int64*)pPrior; |
︙ | ︙ | |||
240 241 242 243 244 245 246 | #if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) int cpuCount; size_t len; if( _sqliteZone_ ){ return SQLITE_OK; } len = sizeof(cpuCount); | | | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | #if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) int cpuCount; size_t len; if( _sqliteZone_ ){ return SQLITE_OK; } len = sizeof(cpuCount); /* One usually wants to use hw.activecpu for MT decisions, but not here */ sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); if( cpuCount>1 ){ /* defer MT decisions to system malloc */ _sqliteZone_ = malloc_default_zone(); }else{ /* only 1 core, use our own zone to contention over global locks, ** e.g. we have our own dedicated locks */ |
︙ | ︙ |
Changes to src/mutex_unix.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | */ #ifdef SQLITE_MUTEX_PTHREADS #include <pthread.h> /* ** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | */ #ifdef SQLITE_MUTEX_PTHREADS #include <pthread.h> /* ** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields ** are necessary under two conditions: (1) Debug builds and (2) using ** home-grown mutexes. Encapsulate these conditions into a single #define. */ #if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX) # define SQLITE_MUTEX_NREF 1 #else # define SQLITE_MUTEX_NREF 0 #endif |
︙ | ︙ |
Changes to src/mutex_w32.c.
︙ | ︙ | |||
34 35 36 37 38 39 40 | /* ** Each recursive mutex is an instance of the following structure. */ struct sqlite3_mutex { CRITICAL_SECTION mutex; /* Mutex controlling the lock */ int id; /* Mutex type */ #ifdef SQLITE_DEBUG | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* ** Each recursive mutex is an instance of the following structure. */ struct sqlite3_mutex { CRITICAL_SECTION mutex; /* Mutex controlling the lock */ int id; /* Mutex type */ #ifdef SQLITE_DEBUG volatile int nRef; /* Number of recursive entrances */ volatile DWORD owner; /* Thread holding this mutex */ volatile LONG trace; /* True to trace changes */ #endif }; /* ** These are the initializer values used when declaring a "static" mutex |
︙ | ︙ |
Changes to src/os.c.
︙ | ︙ | |||
129 130 131 132 133 134 135 | #ifdef SQLITE_TEST if( op!=SQLITE_FCNTL_COMMIT_PHASETWO && op!=SQLITE_FCNTL_LOCK_TIMEOUT ){ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite ** is using a regular VFS, it is called after the corresponding ** transaction has been committed. Injecting a fault at this point | | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | #ifdef SQLITE_TEST if( op!=SQLITE_FCNTL_COMMIT_PHASETWO && op!=SQLITE_FCNTL_LOCK_TIMEOUT ){ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite ** is using a regular VFS, it is called after the corresponding ** transaction has been committed. Injecting a fault at this point ** confuses the test scripts - the COMMIT command returns SQLITE_NOMEM ** but the transaction is committed anyway. ** ** The core must call OsFileControl() though, not OsFileControlHint(), ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably ** means the commit really has failed and an error should be returned ** to the user. */ DO_OS_MALLOC_TEST(id); |
︙ | ︙ |
Changes to src/os.h.
︙ | ︙ | |||
123 124 125 126 127 128 129 | ** byte ranges are used for Unix. This leaves open the possibility of having ** clients on win95, winNT, and unix all talking to the same shared file ** and all locking correctly. To do so would require that samba (or whatever ** tool is being used for file sharing) implements locks correctly between ** windows and unix. I'm guessing that isn't likely to happen, but by ** using the same locking range we are at least open to the possibility. ** | | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | ** byte ranges are used for Unix. This leaves open the possibility of having ** clients on win95, winNT, and unix all talking to the same shared file ** and all locking correctly. To do so would require that samba (or whatever ** tool is being used for file sharing) implements locks correctly between ** windows and unix. I'm guessing that isn't likely to happen, but by ** using the same locking range we are at least open to the possibility. ** ** Locking in windows is mandatory. For this reason, we cannot store ** actual data in the bytes used for locking. The pager never allocates ** the pages involved in locking therefore. SHARED_SIZE is selected so ** that all locks will fit on a single page even at the minimum page size. ** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE ** is set high so that we don't have to allocate an unused page except ** for very large databases. But one should test the page skipping logic ** by setting PENDING_BYTE low and running the entire regression suite. |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
1093 1094 1095 1096 1097 1098 1099 | ** ** Yet another problem: LinuxThreads do not play well with posix locks. ** ** Many older versions of linux use the LinuxThreads library which is ** not posix compliant. Under LinuxThreads, a lock created by thread ** A cannot be modified or overridden by a different thread B. ** Only thread A can modify the lock. Locking behavior is correct | | | 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 | ** ** Yet another problem: LinuxThreads do not play well with posix locks. ** ** Many older versions of linux use the LinuxThreads library which is ** not posix compliant. Under LinuxThreads, a lock created by thread ** A cannot be modified or overridden by a different thread B. ** Only thread A can modify the lock. Locking behavior is correct ** if the application uses the newer Native Posix Thread Library (NPTL) ** on linux - with NPTL a lock created by thread A can override locks ** in thread B. But there is no way to know at compile-time which ** threading library is being used. So there is no way to know at ** compile-time whether or not thread A can override locks on thread B. ** One has to do a run-time check to discover the behavior of the ** current process. ** |
︙ | ︙ | |||
1655 1656 1657 1658 1659 1660 1661 | /* The following describes the implementation of the various locks and ** lock transitions in terms of the POSIX advisory shared and exclusive ** lock primitives (called read-locks and write-locks below, to avoid ** confusion with SQLite lock names). The algorithms are complicated ** slightly in order to be compatible with Windows95 systems simultaneously ** accessing the same database file, in case that is ever required. ** | | | | 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 | /* The following describes the implementation of the various locks and ** lock transitions in terms of the POSIX advisory shared and exclusive ** lock primitives (called read-locks and write-locks below, to avoid ** confusion with SQLite lock names). The algorithms are complicated ** slightly in order to be compatible with Windows95 systems simultaneously ** accessing the same database file, in case that is ever required. ** ** Symbols defined in os.h identify the 'pending byte' and the 'reserved ** byte', each single bytes at well known offsets, and the 'shared byte ** range', a range of 510 bytes at a well known offset. ** ** To obtain a SHARED lock, a read-lock is obtained on the 'pending ** byte'. If this is successful, 'shared byte range' is read-locked ** and the lock on the 'pending byte' released. (Legacy note: When ** SQLite was first developed, Windows95 systems were still very common, ** and Windows95 lacks a shared-lock capability. So on Windows95, a ** single randomly selected by from the 'shared byte range' is locked. ** Windows95 is now pretty much extinct, but this work-around for the ** lack of shared-locks on Windows95 lives on, for backwards ** compatibility.) ** ** A process may only obtain a RESERVED lock after it has a SHARED lock. ** A RESERVED lock is implemented by grabbing a write-lock on the |
︙ | ︙ | |||
1711 1712 1713 1714 1715 1716 1717 | OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, azFileLock(eFileLock))); return SQLITE_OK; } /* Make sure the locking sequence is correct. ** (1) We never move from unlocked to anything higher than shared lock. | | | 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 | OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, azFileLock(eFileLock))); return SQLITE_OK; } /* Make sure the locking sequence is correct. ** (1) We never move from unlocked to anything higher than shared lock. ** (2) SQLite never explicitly requests a pending lock. ** (3) A shared lock is always held when a reserve lock is requested. */ assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); assert( eFileLock!=PENDING_LOCK ); assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); /* This mutex is needed because pFile->pInode is shared across threads |
︙ | ︙ | |||
2929 2930 2931 2932 2933 2934 2935 | OSTRACE(("LOCK %d %s ok (already held) (afp)\n", pFile->h, azFileLock(eFileLock))); return SQLITE_OK; } /* Make sure the locking sequence is correct ** (1) We never move from unlocked to anything higher than shared lock. | | | 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 | OSTRACE(("LOCK %d %s ok (already held) (afp)\n", pFile->h, azFileLock(eFileLock))); return SQLITE_OK; } /* Make sure the locking sequence is correct ** (1) We never move from unlocked to anything higher than shared lock. ** (2) SQLite never explicitly requests a pending lock. ** (3) A shared lock is always held when a reserve lock is requested. */ assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); assert( eFileLock!=PENDING_LOCK ); assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); /* This mutex is needed because pFile->pInode is shared across threads |
︙ | ︙ | |||
3045 3046 3047 3048 3049 3050 3051 | /* Remove the shared lock before trying the range. we'll need to ** reestablish the shared lock if we can't get the afpUnlock */ if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + pInode->sharedByte, 1, 0)) ){ int failed2 = SQLITE_OK; | | | 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 | /* Remove the shared lock before trying the range. we'll need to ** reestablish the shared lock if we can't get the afpUnlock */ if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + pInode->sharedByte, 1, 0)) ){ int failed2 = SQLITE_OK; /* now attempt to get the exclusive lock range */ failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 1); if( failed && (failed2 = afpSetLock(context->dbPath, pFile, SHARED_FIRST + pInode->sharedByte, 1, 1)) ){ /* Can't reestablish the shared lock. Sqlite can't deal, this is ** a critical I/O error */ |
︙ | ︙ | |||
3346 3347 3348 3349 3350 3351 3352 | assert( pFile->pPreallocatedUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE ); #endif #if SQLITE_MAX_MMAP_SIZE>0 | | | 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 | assert( pFile->pPreallocatedUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE ); #endif #if SQLITE_MAX_MMAP_SIZE>0 /* Deal with as much of this read request as possible by transferring ** data from the memory mapping using memcpy(). */ if( offset<pFile->mmapSize ){ if( offset+amt <= pFile->mmapSize ){ memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); return SQLITE_OK; }else{ int nCopy = pFile->mmapSize - offset; |
︙ | ︙ | |||
3481 3482 3483 3484 3485 3486 3487 | pFile->transCntrChng = 1; /* The transaction counter has changed */ } } } #endif #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 | | | 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 | pFile->transCntrChng = 1; /* The transaction counter has changed */ } } } #endif #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 /* Deal with as much of this write request as possible by transferring ** data from the memory mapping using memcpy(). */ if( offset<pFile->mmapSize ){ if( offset+amt <= pFile->mmapSize ){ memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); return SQLITE_OK; }else{ int nCopy = pFile->mmapSize - offset; |
︙ | ︙ | |||
3603 3604 3605 3606 3607 3608 3609 | if( fullSync ) sqlite3_fullsync_count++; sqlite3_sync_count++; #endif /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a ** no-op. But go ahead and call fstat() to validate the file ** descriptor as we need a method to provoke a failure during | | | 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 | if( fullSync ) sqlite3_fullsync_count++; sqlite3_sync_count++; #endif /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a ** no-op. But go ahead and call fstat() to validate the file ** descriptor as we need a method to provoke a failure during ** coverage testing. */ #ifdef SQLITE_NO_SYNC { struct stat buf; rc = osFstat(fd, &buf); } #elif HAVE_FULLFSYNC |
︙ | ︙ | |||
7312 7313 7314 7315 7316 7317 7318 | rc = osFchmod(conchFile->h, cmode); }while( rc==(-1) && errno==EINTR ); if( rc!=0 ){ int code = errno; fprintf(stderr, "fchmod %o FAILED with %d %s\n", cmode, code, strerror(code)); } else { | | | 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 | rc = osFchmod(conchFile->h, cmode); }while( rc==(-1) && errno==EINTR ); if( rc!=0 ){ int code = errno; fprintf(stderr, "fchmod %o FAILED with %d %s\n", cmode, code, strerror(code)); } else { fprintf(stderr, "fchmod %o SUCCEEDED\n",cmode); } }else{ int code = errno; fprintf(stderr, "STAT FAILED[%d] with %d %s\n", err, code, strerror(code)); #endif } |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
2728 2729 2730 2731 2732 2733 2734 | assert( offset>=0 ); SimulateIOError(return SQLITE_IOERR_READ); OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, pFile->h, pBuf, amt, offset, pFile->locktype)); #if SQLITE_MAX_MMAP_SIZE>0 | | | 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 | assert( offset>=0 ); SimulateIOError(return SQLITE_IOERR_READ); OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, pFile->h, pBuf, amt, offset, pFile->locktype)); #if SQLITE_MAX_MMAP_SIZE>0 /* Deal with as much of this read request as possible by transferring ** data from the memory mapping using memcpy(). */ if( offset<pFile->mmapSize ){ if( offset+amt <= pFile->mmapSize ){ memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_OK; |
︙ | ︙ | |||
2806 2807 2808 2809 2810 2811 2812 | SimulateDiskfullError(return SQLITE_FULL); OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, pFile->h, pBuf, amt, offset, pFile->locktype)); #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 | | | 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 | SimulateDiskfullError(return SQLITE_FULL); OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, pFile->h, pBuf, amt, offset, pFile->locktype)); #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 /* Deal with as much of this write request as possible by transferring ** data from the memory mapping using memcpy(). */ if( offset<pFile->mmapSize ){ if( offset+amt <= pFile->mmapSize ){ memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_OK; |
︙ | ︙ | |||
2916 2917 2918 2919 2920 2921 2922 | ** though some folks might complain that the file is bigger than it ** needs to be. ** ** The only feasible work-around is to defer the truncation until after ** all references to memory-mapped content are closed. That is doable, ** but involves adding a few branches in the common write code path which ** could slow down normal operations slightly. Hence, we have decided for | | | 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 | ** though some folks might complain that the file is bigger than it ** needs to be. ** ** The only feasible work-around is to defer the truncation until after ** all references to memory-mapped content are closed. That is doable, ** but involves adding a few branches in the common write code path which ** could slow down normal operations slightly. Hence, we have decided for ** now to simply make truncations a no-op if there are pending reads. We ** can maybe revisit this decision in the future. */ return SQLITE_OK; } #endif assert( pFile ); |
︙ | ︙ | |||
2975 2976 2977 2978 2979 2980 2981 | osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc))); return rc; } #ifdef SQLITE_TEST /* ** Count the number of fullsyncs and normal syncs. This is used to test | | | 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 | osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc))); return rc; } #ifdef SQLITE_TEST /* ** Count the number of fullsyncs and normal syncs. This is used to test ** that syncs and fullsyncs are occurring at the right times. */ int sqlite3_sync_count = 0; int sqlite3_fullsync_count = 0; #endif /* ** Make sure all writes to a particular file are committed to disk. |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
30 31 32 33 34 35 36 | ** journal_mode=MEMORY, or journal_mode=OFF. ** ** Within this comment block, a page is deemed to have been synced ** automatically as soon as it is written when PRAGMA synchronous=OFF. ** Otherwise, the page is not synced until the xSync method of the VFS ** is called successfully on the file containing the page. ** | | | | 30 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 | ** journal_mode=MEMORY, or journal_mode=OFF. ** ** Within this comment block, a page is deemed to have been synced ** automatically as soon as it is written when PRAGMA synchronous=OFF. ** Otherwise, the page is not synced until the xSync method of the VFS ** is called successfully on the file containing the page. ** ** Definition: A page of the database file is said to be "overwritable" if ** one or more of the following are true about the page: ** ** (a) The original content of the page as it was at the beginning of ** the transaction has been written into the rollback journal and ** synced. ** ** (b) The page was a freelist leaf page at the start of the transaction. ** ** (c) The page number is greater than the largest page that existed in ** the database file at the start of the transaction. ** ** (1) A page of the database file is never overwritten unless one of the ** following are true: ** ** (a) The page and all other pages on the same sector are overwritable. ** ** (b) The atomic page write optimization is enabled, and the entire ** transaction other than the update of the transaction sequence ** number consists of a single page change. ** ** (2) The content of a page written into the rollback journal exactly matches ** both the content in the database when the rollback journal was written |
︙ | ︙ | |||
297 298 299 300 301 302 303 | ** instead of READER following such an error. ** ** Once it has entered the ERROR state, any attempt to use the pager ** to read or write data returns an error. Eventually, once all ** outstanding transactions have been abandoned, the pager is able to ** transition back to OPEN state, discarding the contents of the ** page-cache and any other in-memory state at the same time. Everything | | | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | ** instead of READER following such an error. ** ** Once it has entered the ERROR state, any attempt to use the pager ** to read or write data returns an error. Eventually, once all ** outstanding transactions have been abandoned, the pager is able to ** transition back to OPEN state, discarding the contents of the ** page-cache and any other in-memory state at the same time. Everything ** is reloaded from disk (and, if necessary, hot-journal rollback performed) ** when a read-transaction is next opened on the pager (transitioning ** the pager into READER state). At that point the system has recovered ** from the error. ** ** Specifically, the pager jumps into the ERROR state if: ** ** 1. An error occurs while attempting a rollback. This happens in |
︙ | ︙ | |||
1722 1723 1724 1725 1726 1727 1728 | || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nSuper+8))) ){ return rc; } pPager->journalOff += (nSuper+20); | | | 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 | || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nSuper+8))) ){ return rc; } pPager->journalOff += (nSuper+20); /* If the pager is in persistent-journal mode, then the physical ** journal-file may extend past the end of the super-journal name ** and 8 bytes of magic data just written to the file. This is ** dangerous because the code to rollback a hot-journal file ** will not be able to find the super-journal name to determine ** whether or not the journal is hot. ** ** Easiest thing to do in this scenario is to truncate the journal |
︙ | ︙ | |||
1892 1893 1894 1895 1896 1897 1898 | pPager->journalOff = 0; pPager->journalHdr = 0; pPager->setSuper = 0; } /* ** This function is called whenever an IOERR or FULL error that requires | | | 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 | pPager->journalOff = 0; pPager->journalHdr = 0; pPager->setSuper = 0; } /* ** This function is called whenever an IOERR or FULL error that requires ** the pager to transition into the ERROR state may have occurred. ** The first argument is a pointer to the pager structure, the second ** the error-code about to be returned by a pager API function. The ** value returned is a copy of the second argument to this function. ** ** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the ** IOERR sub-codes, the pager enters the ERROR state and the error code ** is stored in Pager.errCode. While the pager remains in the ERROR state, |
︙ | ︙ | |||
3116 3117 3118 3119 3120 3121 3122 | int rc; /* Return code */ int nList; /* Number of pages in pList */ PgHdr *p; /* For looping over pages */ assert( pPager->pWal ); assert( pList ); #ifdef SQLITE_DEBUG | | | 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 | int rc; /* Return code */ int nList; /* Number of pages in pList */ PgHdr *p; /* For looping over pages */ assert( pPager->pWal ); assert( pList ); #ifdef SQLITE_DEBUG /* Verify that the page list is in ascending order */ for(p=pList; p && p->pDirty; p=p->pDirty){ assert( p->pgno < p->pDirty->pgno ); } #endif assert( pList->pDirty==0 || isCommit ); if( isCommit ){ |
︙ | ︙ | |||
3499 3500 3501 3502 3503 3504 3505 | ** ** OFF sqlite3OsSync() is never called. This is the default ** for temporary and transient files. ** ** NORMAL The journal is synced once before writes begin on the ** database. This is normally adequate protection, but ** it is theoretically possible, though very unlikely, | | | 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 | ** ** OFF sqlite3OsSync() is never called. This is the default ** for temporary and transient files. ** ** NORMAL The journal is synced once before writes begin on the ** database. This is normally adequate protection, but ** it is theoretically possible, though very unlikely, ** that an inopportune power failure could leave the journal ** in a state which would cause damage to the database ** when it is rolled back. ** ** FULL The journal is synced twice before writes begin on the ** database (with some additional information - the nRec field ** of the journal header - being written in between the two ** syncs). If we assume that writing a |
︙ | ︙ | |||
5005 5006 5007 5008 5009 5010 5011 | *ppPager = pPager; return SQLITE_OK; } /* ** Return the sqlite3_file for the main database given the name | | | 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 | *ppPager = pPager; return SQLITE_OK; } /* ** Return the sqlite3_file for the main database given the name ** of the corresponding WAL or Journal name as passed into ** xOpen. */ sqlite3_file *sqlite3_database_file_object(const char *zName){ Pager *pPager; while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){ zName--; } |
︙ | ︙ | |||
7274 7275 7276 7277 7278 7279 7280 | if( eMode!=eOld ){ /* Change the journal mode. */ assert( pPager->eState!=PAGER_ERROR ); pPager->journalMode = (u8)eMode; | | | 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 | if( eMode!=eOld ){ /* Change the journal mode. */ assert( pPager->eState!=PAGER_ERROR ); pPager->journalMode = (u8)eMode; /* When transitioning from TRUNCATE or PERSIST to any other journal ** mode except WAL, unless the pager is in locking_mode=exclusive mode, ** delete the journal file. */ assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); assert( (PAGER_JOURNALMODE_DELETE & 5)==0 ); assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 ); |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
245 246 247 248 249 250 251 | GENERATED ALWAYS %endif REINDEX RENAME CTIME_KW IF . %wildcard ANY. // Define operator precedence early so that this is the first occurrence | | | 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | GENERATED ALWAYS %endif REINDEX RENAME CTIME_KW IF . %wildcard ANY. // Define operator precedence early so that this is the first occurrence // of the operator tokens in the grammar. Keeping the operators together // causes them to be assigned integer values that are close together, // which keeps parser tables smaller. // // The token values assigned to these symbols is determined by the order // in which lemon first sees them. It must be the case that ISNULL/NOTNULL, // NE/EQ, GT/LE, and GE/LT are separated by only a single value. See // the sqlite3ExprIfFalse() routine for additional information on this |
︙ | ︙ | |||
752 753 754 755 756 757 758 | joinop(X) ::= JOIN_KW(A) JOIN. {X = sqlite3JoinType(pParse,&A,0,0); /*X-overwrites-A*/} joinop(X) ::= JOIN_KW(A) nm(B) JOIN. {X = sqlite3JoinType(pParse,&A,&B,0); /*X-overwrites-A*/} joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN. {X = sqlite3JoinType(pParse,&A,&B,&C);/*X-overwrites-A*/} | | | 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 | joinop(X) ::= JOIN_KW(A) JOIN. {X = sqlite3JoinType(pParse,&A,0,0); /*X-overwrites-A*/} joinop(X) ::= JOIN_KW(A) nm(B) JOIN. {X = sqlite3JoinType(pParse,&A,&B,0); /*X-overwrites-A*/} joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN. {X = sqlite3JoinType(pParse,&A,&B,&C);/*X-overwrites-A*/} // There is a parsing ambiguity in an upsert statement that uses a // SELECT on the RHS of a the INSERT: // // INSERT INTO tab SELECT * FROM aaa JOIN bbb ON CONFLICT ... // here ----^^ // // When the ON token is encountered, the parser does not know if it is // the beginning of an ON CONFLICT clause, or the beginning of an ON |
︙ | ︙ |
Changes to src/pcache.c.
︙ | ︙ | |||
239 240 241 242 243 244 245 | */ static int numberOfCachePages(PCache *p){ if( p->szCache>=0 ){ /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the ** suggested cache size is set to N. */ return p->szCache; }else{ | | | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | */ static int numberOfCachePages(PCache *p){ if( p->szCache>=0 ){ /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the ** suggested cache size is set to N. */ return p->szCache; }else{ /* IMPLEMENTATION-OF: R-59858-46238 If the argument N is negative, then the ** number of cache pages is adjusted to be a number of pages that would ** use approximately abs(N*1024) bytes of memory based on the current ** page size. */ return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); } } |
︙ | ︙ | |||
712 713 714 715 716 717 718 | } } } return result.pDirty; } /* | | | 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 | } } } return result.pDirty; } /* ** Sort the list of pages in ascending order by pgno. Pages are ** connected by pDirty pointers. The pDirtyPrev pointers are ** corrupted by this sort. ** ** Since there cannot be more than 2^31 distinct pages in a database, ** there cannot be more than 31 buckets required by the merge sorter. ** One extra bucket is added to catch overflow in case something ** ever changes to make the previous sentence incorrect. |
︙ | ︙ |
Changes to src/pcache1.c.
︙ | ︙ | |||
95 96 97 98 99 100 101 | ** ** Note: Variables isBulkLocal and isAnchor were once type "u8". That works, ** but causes a 2-byte gap in the structure for most architectures (since ** pointers must be either 4 or 8-byte aligned). As this structure is located ** in memory directly after the associated page data, if the database is ** corrupt, code at the b-tree layer may overread the page buffer and ** read part of this structure before the corruption is detected. This | | | | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | ** ** Note: Variables isBulkLocal and isAnchor were once type "u8". That works, ** but causes a 2-byte gap in the structure for most architectures (since ** pointers must be either 4 or 8-byte aligned). As this structure is located ** in memory directly after the associated page data, if the database is ** corrupt, code at the b-tree layer may overread the page buffer and ** read part of this structure before the corruption is detected. This ** can cause a valgrind error if the uninitialized gap is accessed. Using u16 ** ensures there is no such gap, and therefore no bytes of uninitialized memory ** in the structure. */ struct PgHdr1 { sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ unsigned int iKey; /* Key value (page number) */ u16 isBulkLocal; /* This page from bulk local storage */ u16 isAnchor; /* This is the PGroup.lru element */ |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
837 838 839 840 841 842 843 | /* ** PRAGMA [schema.]cache_spill ** PRAGMA cache_spill=BOOLEAN ** PRAGMA [schema.]cache_spill=N ** ** The first form reports the current local setting for the ** page cache spill size. The second form turns cache spill on | | | 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 | /* ** PRAGMA [schema.]cache_spill ** PRAGMA cache_spill=BOOLEAN ** PRAGMA [schema.]cache_spill=N ** ** The first form reports the current local setting for the ** page cache spill size. The second form turns cache spill on ** or off. When turning cache spill on, the size is set to the ** current cache_size. The third form sets a spill size that ** may be different form the cache size. ** If N is positive then that is the ** number of pages in the cache. If N is negative, then the ** number of pages is adjusted so that the cache uses -N kibibytes ** of memory. ** |
︙ | ︙ | |||
1515 1516 1517 1518 1519 1520 1521 | ** PRAGMA quick_check(N) ** ** Verify the integrity of the database. ** ** The "quick_check" is reduced version of ** integrity_check designed to detect most database corruption ** without the overhead of cross-checking indexes. Quick_check | | | | 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 | ** PRAGMA quick_check(N) ** ** Verify the integrity of the database. ** ** The "quick_check" is reduced version of ** integrity_check designed to detect most database corruption ** without the overhead of cross-checking indexes. Quick_check ** is linear time whereas integrity_check is O(NlogN). ** ** The maximum number of errors is 100 by default. A different default ** can be specified using a numeric parameter N. ** ** Or, the parameter N can be the name of a table. In that case, only ** the one table named is verified. The freelist is only verified if ** the named table is "sqlite_schema" (or one of its aliases). ** ** All schemas are checked by default. To check just a single |
︙ | ︙ |
Changes to src/printf.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | /* ** Conversion types fall into various categories as defined by the ** following enumeration. */ #define etRADIX 0 /* non-decimal integer types. %x %o */ #define etFLOAT 1 /* Floating point. %f */ | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* ** Conversion types fall into various categories as defined by the ** following enumeration. */ #define etRADIX 0 /* non-decimal integer types. %x %o */ #define etFLOAT 1 /* Floating point. %f */ #define etEXP 2 /* Exponental notation. %e and %E */ #define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */ #define etSIZE 4 /* Return number of characters processed so far. %n */ #define etSTRING 5 /* Strings. %s */ #define etDYNSTRING 6 /* Dynamically allocated strings. %z */ #define etPERCENT 7 /* Percent symbol. %% */ #define etCHARX 8 /* Characters. %c */ /* The rest are extensions, not normally found in printf() */ |
︙ | ︙ |
Changes to src/resolve.c.
︙ | ︙ | |||
908 909 910 911 912 913 914 | if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 && pParse->nested==0 && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0 ){ /* Internal-use-only functions are disallowed unless the ** SQL is being compiled using sqlite3NestedParse() or ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be | | | 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 | if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 && pParse->nested==0 && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0 ){ /* Internal-use-only functions are disallowed unless the ** SQL is being compiled using sqlite3NestedParse() or ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be ** used to activate internal functions for testing purposes */ no_such_func = 1; pDef = 0; }else if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 && !IN_RENAME_OBJECT ){ sqlite3ExprFunctionUsable(pParse, pExpr, pDef); |
︙ | ︙ | |||
1300 1301 1302 1303 1304 1305 1306 | ** is deleted. ** ** Or, if this is running as part of an ALTER TABLE operation, ** resolve the symbols in the actual expression, not a duplicate. ** And, if one of the comparisons is successful, leave the expression ** as is instead of transforming it to an integer as in the usual ** case. This allows the code in alter.c to modify column | | | 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 | ** is deleted. ** ** Or, if this is running as part of an ALTER TABLE operation, ** resolve the symbols in the actual expression, not a duplicate. ** And, if one of the comparisons is successful, leave the expression ** as is instead of transforming it to an integer as in the usual ** case. This allows the code in alter.c to modify column ** references within the ORDER BY expression as required. */ if( IN_RENAME_OBJECT ){ pDup = pE; }else{ pDup = sqlite3ExprDup(db, pE, 0); } if( !db->mallocFailed ){ assert(pDup); |
︙ | ︙ | |||
1489 1490 1491 1492 1493 1494 1495 | /* Otherwise, treat the ORDER BY term as an ordinary expression */ pItem->u.x.iOrderByCol = 0; if( sqlite3ResolveExprNames(pNC, pE) ){ return 1; } for(j=0; j<pSelect->pEList->nExpr; j++){ if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ | | | 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 | /* Otherwise, treat the ORDER BY term as an ordinary expression */ pItem->u.x.iOrderByCol = 0; if( sqlite3ResolveExprNames(pNC, pE) ){ return 1; } for(j=0; j<pSelect->pEList->nExpr; j++){ if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ /* Since this expression 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; } } } |
︙ | ︙ | |||
1872 1873 1874 1875 1876 1877 1878 | } pNC->ncFlags |= savedHasAgg; return WRC_Continue; } /* ** Resolve all names in all expressions of a SELECT and in all | | | 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 | } pNC->ncFlags |= savedHasAgg; return WRC_Continue; } /* ** Resolve all names in all expressions of a SELECT and in all ** descendents of the SELECT, including compounds off of p->pPrior, ** subqueries in expressions, and subqueries used as FROM clause ** terms. ** ** See sqlite3ResolveExprNames() for a description of the kinds of ** transformations that occur. ** ** All SELECT statements should have been expanded using |
︙ | ︙ |
Changes to src/rowset.c.
︙ | ︙ | |||
38 39 40 41 42 43 44 | ** allocated in chunks so most INSERTs do no allocation. There is an ** upper bound on the size of allocated memory. No memory is freed ** until DESTROY. ** ** The TEST primitive includes a "batch" number. The TEST primitive ** will only see elements that were inserted before the last change ** in the batch number. In other words, if an INSERT occurs between | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | ** allocated in chunks so most INSERTs do no allocation. There is an ** upper bound on the size of allocated memory. No memory is freed ** until DESTROY. ** ** The TEST primitive includes a "batch" number. The TEST primitive ** will only see elements that were inserted before the last change ** in the batch number. In other words, if an INSERT occurs between ** two TESTs where the TESTs have the same batch number, then the ** value added by the INSERT will not be visible to the second TEST. ** The initial batch number is zero, so if the very first TEST contains ** a non-zero batch number, it will see all prior INSERTs. ** ** No INSERTs may occurs after a SMALLEST. An assertion will fail if ** that is attempted. ** |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
607 608 609 610 611 612 613 | ** by a prior OP_MakeRecord. In this case nData==1 and regData ** will be completely unrelated to regOrigData. ** (2) All output columns are included in the sort record. In that ** case regData==regOrigData. ** (3) Some output columns are omitted from the sort record due to ** the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the ** SQLITE_ECEL_OMITREF optimization, or due to the | | | 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 | ** by a prior OP_MakeRecord. In this case nData==1 and regData ** will be completely unrelated to regOrigData. ** (2) All output columns are included in the sort record. In that ** case regData==regOrigData. ** (3) Some output columns are omitted from the sort record due to ** the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the ** SQLITE_ECEL_OMITREF optimization, or due to the ** SortCtx.pDeferredRowLoad optimization. In any of these cases ** regOrigData is 0 to prevent this routine from trying to copy ** values that might not yet exist. */ assert( nData==1 || regData==regOrigData || regOrigData==0 ); if( nPrefixReg ){ assert( nPrefixReg==nExpr+bSeq ); |
︙ | ︙ | |||
2343 2344 2345 2346 2347 2348 2349 | int addrTop; /* Top of the loop */ int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ int iCurrent = 0; /* The Current table */ int regCurrent; /* Register holding Current table */ int iQueue; /* The Queue table */ int iDistinct = 0; /* To ensure unique results if UNION */ int eDest = SRT_Fifo; /* How to write to Queue */ | | | 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 | int addrTop; /* Top of the loop */ int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ int iCurrent = 0; /* The Current table */ int regCurrent; /* Register holding Current table */ int iQueue; /* The Queue table */ int iDistinct = 0; /* To ensure unique results if UNION */ int eDest = SRT_Fifo; /* How to write to Queue */ SelectDest destQueue; /* SelectDest targeting the Queue table */ int i; /* Loop counter */ int rc; /* Result code */ ExprList *pOrderBy; /* The ORDER BY clause */ Expr *pLimit; /* Saved LIMIT and OFFSET */ int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */ #ifndef SQLITE_OMIT_WINDOWFUNC |
︙ | ︙ | |||
2487 2488 2489 2490 2491 2492 2493 | ** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1 ** (2) All terms are UNION ALL ** (3) There is no ORDER BY clause ** ** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES ** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))"). ** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case. | | | 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 | ** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1 ** (2) All terms are UNION ALL ** (3) There is no ORDER BY clause ** ** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES ** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))"). ** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case. ** Since the limit is exactly 1, we only need to evaluate the left-most VALUES. */ static int multiSelectValues( Parse *pParse, /* Parsing context */ Select *p, /* The right-most of SELECTs to be coded */ SelectDest *pDest /* What to do with query results */ ){ int nRow = 1; |
︙ | ︙ | |||
2911 2912 2913 2914 2915 2916 2917 | sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" " do not have the same number of result columns", selectOpName(p->op)); } } /* ** Code an output subroutine for a coroutine implementation of a | | | 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 | sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" " do not have the same number of result columns", selectOpName(p->op)); } } /* ** Code an output subroutine for a coroutine implementation of a ** SELECT statement. ** ** The data to be output is contained in pIn->iSdst. There are ** pIn->nSdst columns to be output. pDest is where the output should ** be sent. ** ** regReturn is the number of the register holding the subroutine ** return address. |
︙ | ︙ | |||
4115 4116 4117 4118 4119 4120 4121 | ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". */ if( pSub->pOrderBy && (pParent->selFlags & SF_NoopOrderBy)==0 ){ /* At this point, any non-zero iOrderByCol values indicate that the ** ORDER BY column expression is identical to the iOrderByCol'th ** expression returned by SELECT statement pSub. Since these values ** do not necessarily correspond to columns in SELECT statement pParent, | | | 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 | ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". */ if( pSub->pOrderBy && (pParent->selFlags & SF_NoopOrderBy)==0 ){ /* At this point, any non-zero iOrderByCol values indicate that the ** ORDER BY column expression is identical to the iOrderByCol'th ** expression returned by SELECT statement pSub. Since these values ** do not necessarily correspond to columns in SELECT statement pParent, ** zero them before transferring the ORDER BY clause. ** ** Not doing this may cause an error if a subsequent call to this ** function attempts to flatten a compound sub-query into pParent ** (the only way this can happen is if the compound sub-query is ** currently part of pSub->pSrc). See ticket [d11a6e908f]. */ ExprList *pOrderBy = pSub->pOrderBy; for(i=0; i<pOrderBy->nExpr; i++){ |
︙ | ︙ | |||
4174 4175 4176 4177 4178 4179 4180 | /* Recompute the SrcList_item.colUsed masks for the flattened ** tables. */ for(i=0; i<nSubSrc; i++){ recomputeColumnsUsed(pParent, &pSrc->a[i+iFrom]); } } | | | 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 | /* Recompute the SrcList_item.colUsed masks for the flattened ** tables. */ for(i=0; i<nSubSrc; i++){ recomputeColumnsUsed(pParent, &pSrc->a[i+iFrom]); } } /* Finally, delete what is left of the subquery and return ** success. */ sqlite3AggInfoPersistWalkerInit(&w, pParse); sqlite3WalkSelect(&w,pSub1); sqlite3SelectDelete(db, pSub1); #if SELECTTRACE_ENABLED |
︙ | ︙ | |||
5895 5896 5897 5898 5899 5900 5901 | ){ SELECTTRACE(0x100,pParse,p, ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); unsetJoinExpr(p->pWhere, pItem->iCursor); } | | | 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 | ){ SELECTTRACE(0x100,pParse,p, ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); unsetJoinExpr(p->pWhere, pItem->iCursor); } /* No further action if this term of the FROM clause is no a subquery */ if( pSub==0 ) continue; /* Catch mismatch in the declared columns of a view and the number of ** columns in the SELECT on the RHS */ if( pTab->nCol!=pSub->pEList->nExpr ){ sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d", pTab->nCol, pTab->zName, pSub->pEList->nExpr); |
︙ | ︙ | |||
6478 6479 6480 6481 6482 6483 6484 | /* Processing for aggregates with GROUP BY is very different and ** much more complex than aggregates without a GROUP BY. */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ | | | 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 | /* Processing for aggregates with GROUP BY is very different and ** much more complex than aggregates without a GROUP BY. */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ int addr1; /* A-vs-B comparison jump */ int addrOutputRow; /* Start of subroutine that outputs a result row */ int regOutputRow; /* Return address register for output subroutine */ int addrSetAbort; /* Set the abort flag and return */ int addrTopOfLoop; /* Top of the input loop */ int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ int addrReset; /* Subroutine for resetting the accumulator */ int regReset; /* Return address register for reset subroutine */ |
︙ | ︙ |
Changes to src/shell.c.in.
︙ | ︙ | |||
1079 1080 1081 1082 1083 1084 1085 | ** State information about the database connection is contained in an ** instance of the following structure. */ typedef struct ShellState ShellState; struct ShellState { sqlite3 *db; /* The database */ u8 autoExplain; /* Automatically turn on .explain mode */ | | | | 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 | ** State information about the database connection is contained in an ** instance of the following structure. */ typedef struct ShellState ShellState; struct ShellState { sqlite3 *db; /* The database */ u8 autoExplain; /* Automatically turn on .explain mode */ u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to each SQL stmt */ u8 autoEQPtest; /* autoEQP is in test mode */ u8 autoEQPtrace; /* autoEQP is in trace mode */ u8 statsOn; /* True to display memory stats before each finalize */ u8 scanstatsOn; /* True to display scan stats before each finalize */ u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ u8 nEqpLevel; /* Depth of the EQP output graph */ u8 eTraceType; /* SHELL_TRACE_* value for type of trace */ unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ int lineno; /* Line number of last line read from in */ int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */ FILE *in; /* Read commands from this stream */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ |
︙ | ︙ | |||
1499 1500 1501 1502 1503 1504 1505 | raw_printf(out, "'"); } setTextMode(out, 1); } /* ** Output the given string as a quoted string using SQL quoting conventions. | | | 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 | raw_printf(out, "'"); } setTextMode(out, 1); } /* ** Output the given string as a quoted string using SQL quoting conventions. ** Additionally , escape the "\n" and "\r" characters so that they do not ** get corrupted by end-of-line translation facilities in some operating ** systems. ** ** This is like output_quoted_string() but with the addition of the \r\n ** escape mechanism. */ static void output_quoted_escaped_string(FILE *out, const char *z){ |
︙ | ︙ | |||
3430 3431 3432 3433 3434 3435 3436 | while( IsSpace(zSql[0]) ) zSql++; continue; } zStmtSql = sqlite3_sql(pStmt); if( zStmtSql==0 ) zStmtSql = ""; while( IsSpace(zStmtSql[0]) ) zStmtSql++; | | | 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 | while( IsSpace(zSql[0]) ) zSql++; continue; } zStmtSql = sqlite3_sql(pStmt); if( zStmtSql==0 ) zStmtSql = ""; while( IsSpace(zStmtSql[0]) ) zStmtSql++; /* save off the prepared statement handle and reset row count */ if( pArg ){ pArg->pStmt = pStmt; pArg->cnt = 0; } /* echo the sql statement if echo on */ if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){ |
︙ | ︙ | |||
3481 3482 3483 3484 3485 3486 3487 | explain_data_delete(pArg); } sqlite3_finalize(pExplain); sqlite3_free(zEQP); } if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){ sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0); | | | 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 | explain_data_delete(pArg); } sqlite3_finalize(pExplain); sqlite3_free(zEQP); } if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){ sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0); /* Reprepare pStmt before reactivating trace modes */ sqlite3_finalize(pStmt); sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); if( pArg ) pArg->pStmt = pStmt; } restore_debug_trace_modes(); } |
︙ | ︙ | |||
3616 3617 3618 3619 3620 3621 3622 | ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve ** rowids on tables where the rowid is inaccessible because there are other ** columns in the table named "rowid", "_rowid_", and "oid". */ if( preserveRowid && isIPK ){ /* If a single PRIMARY KEY column with type INTEGER was seen, then it | | | 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 | ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve ** rowids on tables where the rowid is inaccessible because there are other ** columns in the table named "rowid", "_rowid_", and "oid". */ if( preserveRowid && isIPK ){ /* If a single PRIMARY KEY column with type INTEGER was seen, then it ** might be an alias for the ROWID. But it might also be a WITHOUT ROWID ** table or a INTEGER PRIMARY KEY DESC column, neither of which are ** ROWID aliases. To distinguish these cases, check to see if ** there is a "pk" entry in "PRAGMA index_list". There will be ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID. */ zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" " WHERE origin='pk'", zTab); |
︙ | ︙ | |||
3827 3828 3829 3830 3831 3832 3833 | return rc; } /* ** Text of help messages. ** ** The help text for each individual command begins with a line that starts | | | 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 | return rc; } /* ** Text of help messages. ** ** The help text for each individual command begins with a line that starts ** with ".". Subsequent lines are supplemental information. ** ** There must be two or more spaces between the end of the command and the ** start of the description of what that command does. */ static const char *(azHelp[]) = { #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) ".archive ... Manage SQL archives", |
︙ | ︙ | |||
3953 3954 3955 3956 3957 3958 3959 | #ifdef SQLITE_DEBUG ".oom ?--repeat M? ?N? Simulate an OOM error on the N-th allocation", #endif ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE", " Options:", " --append Use appendvfs to append database to the end of FILE", #ifdef SQLITE_ENABLE_DESERIALIZE | | | 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 | #ifdef SQLITE_DEBUG ".oom ?--repeat M? ?N? Simulate an OOM error on the N-th allocation", #endif ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE", " Options:", " --append Use appendvfs to append database to the end of FILE", #ifdef SQLITE_ENABLE_DESERIALIZE " --deserialize Load into memory using 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", " --nofollow Do not follow symbolic links", " --readonly Open FILE readonly", " --zip FILE is a ZIP archive", |
︙ | ︙ | |||
4631 4632 4633 4634 4635 4636 4637 | } } #endif } } /* | | | 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 | } } #endif } } /* ** Attempt to close the database connection. Report errors. */ void close_db(sqlite3 *db){ int rc = sqlite3_close(db); if( rc ){ utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db)); } |
︙ | ︙ | |||
10819 10820 10821 10822 10823 10824 10825 | for(i=1; i<argc; i++){ char *z; z = argv[i]; if( z[0]!='-' ){ if( data.zDbFilename==0 ){ data.zDbFilename = z; }else{ | | | 10819 10820 10821 10822 10823 10824 10825 10826 10827 10828 10829 10830 10831 10832 10833 | for(i=1; i<argc; i++){ char *z; z = argv[i]; if( z[0]!='-' ){ if( data.zDbFilename==0 ){ data.zDbFilename = z; }else{ /* Excess arguments are interpreted as SQL (or dot-commands) and ** mean that nothing is read from stdin */ readStdin = 0; nCmd++; azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd); if( azCmd==0 ) shell_out_of_memory(); azCmd[nCmd-1] = z; } |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
2318 2319 2320 2321 2322 2323 2324 | ** practical use, but is provided so that SQLite can continue to claim the ** ability to generate new database files that are compatible with version ** 3.0.0. ** <p>Note that when the SQLITE_DBCONFIG_LEGACY_FILE_FORMAT setting is on, ** the [VACUUM] command will fail with an obscure error when attempting to ** process a table with generated columns and a descending index. This is ** not considered a bug since SQLite versions 3.3.0 and earlier do not support | | | 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 | ** practical use, but is provided so that SQLite can continue to claim the ** ability to generate new database files that are compatible with version ** 3.0.0. ** <p>Note that when the SQLITE_DBCONFIG_LEGACY_FILE_FORMAT setting is on, ** the [VACUUM] command will fail with an obscure error when attempting to ** process a table with generated columns and a descending index. This is ** not considered a bug since SQLite versions 3.3.0 and earlier do not support ** either generated columns or descending indexes. ** </dd> ** </dl> */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ |
︙ | ︙ | |||
3543 3544 3545 3546 3547 3548 3549 | ** that check if a database file was a URI that contained a specific query ** parameter, and if so obtains the value of that query parameter. ** ** The first parameter to these interfaces (hereafter referred to ** as F) must be one of: ** <ul> ** <li> A database filename pointer created by the SQLite core and | | | 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 | ** that check if a database file was a URI that contained a specific query ** parameter, and if so obtains the value of that query parameter. ** ** The first parameter to these interfaces (hereafter referred to ** as F) must be one of: ** <ul> ** <li> A database filename pointer created by the SQLite core and ** passed into the xOpen() method of a VFS implementation, or ** <li> A filename obtained from [sqlite3_db_filename()], or ** <li> A new filename constructed using [sqlite3_create_filename()]. ** </ul> ** If the F parameter is not one of the above, then the behavior is ** undefined and probably undesirable. Older versions of SQLite were ** more tolerant of invalid F parameters than newer versions. ** |
︙ | ︙ | |||
3656 3657 3658 3659 3660 3661 3662 | ** behavior. */ sqlite3_file *sqlite3_database_file_object(const char*); /* ** CAPI3REF: Create and Destroy VFS Filenames ** | | | 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 | ** behavior. */ sqlite3_file *sqlite3_database_file_object(const char*); /* ** CAPI3REF: Create and Destroy VFS Filenames ** ** These interfaces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of ** database filename D with corresponding journal file J and WAL file W and ** with N URI parameters key/values pairs in the array P. The result from ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that ** is safe to pass to routines like: |
︙ | ︙ | |||
9151 9152 9153 9154 9155 9156 9157 | ** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT ** constraint handling. ** </dd> ** ** [[SQLITE_VTAB_DIRECTONLY]]<dt>SQLITE_VTAB_DIRECTONLY</dt> ** <dd>Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the | | | | 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 | ** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT ** constraint handling. ** </dd> ** ** [[SQLITE_VTAB_DIRECTONLY]]<dt>SQLITE_VTAB_DIRECTONLY</dt> ** <dd>Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the ** the [xConnect] or [xCreate] methods of a [virtual table] implementation ** prohibits that virtual table from being used from within triggers and ** views. ** </dd> ** ** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt> ** <dd>Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the ** the [xConnect] or [xCreate] methods of a [virtual table] implementation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a ** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS ** flag unless absolutely necessary. ** </dd> ** </dl> |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
661 662 663 664 665 666 667 | /* ** The default initial allocation for the pagecache when using separate ** pagecaches for each database connection. A positive number is the ** number of pages. A negative number N translations means that a buffer ** of -1024*N bytes is allocated and used for as many pages as it will hold. ** | | | 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 | /* ** The default initial allocation for the pagecache when using separate ** pagecaches for each database connection. A positive number is the ** number of pages. A negative number N translations means that a buffer ** of -1024*N bytes is allocated and used for as many pages as it will hold. ** ** The default value of "20" was chosen to minimize the run-time of the ** speedtest1 test program with options: --shrink-memory --reprepare */ #ifndef SQLITE_DEFAULT_PCACHE_INITSZ # define SQLITE_DEFAULT_PCACHE_INITSZ 20 #endif /* |
︙ | ︙ | |||
1239 1240 1241 1242 1243 1244 1245 | Schema *pSchema; /* Pointer to database schema (possibly shared) */ }; /* ** An instance of the following structure stores a database schema. ** ** Most Schema objects are associated with a Btree. The exception is | | | 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 | Schema *pSchema; /* Pointer to database schema (possibly shared) */ }; /* ** An instance of the following structure stores a database schema. ** ** Most Schema objects are associated with a Btree. The exception is ** the Schema for the TEMP database (sqlite3.aDb[1]) which is free-standing. ** In shared cache mode, a single Schema object can be shared by multiple ** Btrees that refer to the same underlying BtShared object. ** ** Schema objects are automatically deallocated when the last Btree that ** references them is destroyed. The TEMP Schema is manually freed by ** sqlite3_close(). * |
︙ | ︙ | |||
1350 1351 1352 1353 1354 1355 1356 | u16 szTrue; /* True value of sz, even if disabled */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ u32 nSlot; /* Number of lookaside slots allocated */ u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ LookasideSlot *pInit; /* List of buffers not previously used */ LookasideSlot *pFree; /* List of available buffers */ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE | | | 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 | u16 szTrue; /* True value of sz, even if disabled */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ u32 nSlot; /* Number of lookaside slots allocated */ u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ LookasideSlot *pInit; /* List of buffers not previously used */ LookasideSlot *pFree; /* List of available buffers */ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE LookasideSlot *pSmallInit; /* List of small buffers not previously used */ LookasideSlot *pSmallFree; /* List of available small buffers */ void *pMiddle; /* First byte past end of full-size buffers and ** the first byte of LOOKASIDE_SMALL buffers */ #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ void *pStart; /* First byte of available memory space */ void *pEnd; /* First byte past end of available space */ }; |
︙ | ︙ | |||
2660 2661 2662 2663 2664 2665 2666 | #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 | | | 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 | #if SQLITE_MAX_EXPR_DEPTH>0 int nHeight; /* Height of the tree headed by this node */ #endif int iTable; /* TK_COLUMN: cursor number of table holding column ** TK_REGISTER: register number ** TK_TRIGGER: 1 -> new, 0 -> old ** EP_Unlikely: 134217728 times likelihood ** TK_IN: ephemeral table holding RHS ** TK_SELECT_COLUMN: Number of columns on the LHS ** TK_SELECT: 1st register of result vector */ ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. ** TK_VARIABLE: variable number (always >= 1). ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ |
︙ | ︙ |
Changes to src/sqliteLimit.h.
︙ | ︙ | |||
72 73 74 75 76 77 78 | /* ** The maximum number of terms in a compound SELECT statement. ** The code generator for compound SELECT statements does one ** level of recursion for each term. A stack overflow can result ** if the number of terms is too large. In practice, most SQL ** never has more than 3 or 4 terms. Use a value of 0 to disable | | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | /* ** The maximum number of terms in a compound SELECT statement. ** The code generator for compound SELECT statements does one ** level of recursion for each term. A stack overflow can result ** if the number of terms is too large. In practice, most SQL ** never has more than 3 or 4 terms. Use a value of 0 to disable ** any limit on the number of terms in a compound SELECT. */ #ifndef SQLITE_MAX_COMPOUND_SELECT # define SQLITE_MAX_COMPOUND_SELECT 500 #endif /* ** The maximum number of opcodes in a VDBE program. |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
1752 1753 1754 1755 1756 1757 1758 | } return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1); } /* ** If using Tcl version 8.6 or greater, use the NR functions to avoid | | | 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 | } return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1); } /* ** If using Tcl version 8.6 or greater, use the NR functions to avoid ** recursive evaluation of scripts by the [db eval] and [db trans] ** commands. Even if the headers used while compiling the extension ** are 8.6 or newer, the code still tests the Tcl version at runtime. ** This allows stubs-enabled builds to be used with older Tcl libraries. */ #if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6) # define SQLITE_TCL_NRE 1 static int DbUseNre(void){ |
︙ | ︙ | |||
3382 3383 3384 3385 3386 3387 3388 | } /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT ** ** Start a new transaction (if we are not already in the midst of a ** transaction) and execute the TCL script SCRIPT. After SCRIPT ** completes, either commit the transaction or roll it back if SCRIPT | | | 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 | } /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT ** ** Start a new transaction (if we are not already in the midst of a ** transaction) and execute the TCL script SCRIPT. After SCRIPT ** completes, either commit the transaction or roll it back if SCRIPT ** throws an exception. Or if no new transaction was started, do nothing. ** pass the exception on up the stack. ** ** This command was inspired by Dave Thomas's talk on Ruby at the ** 2005 O'Reilly Open Source Convention (OSCON). */ case DB_TRANSACTION: { Tcl_Obj *pScript; |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
2636 2637 2638 2639 2640 2641 2642 | sqlite3_close(db); return TCL_OK; } /* ** Usage: sqlite3_next_stmt DB STMT ** | | | 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 | sqlite3_close(db); return TCL_OK; } /* ** Usage: sqlite3_next_stmt DB STMT ** ** Return the next statement in sequence after STMT. */ static int SQLITE_TCLAPI test_next_stmt( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ |
︙ | ︙ | |||
5644 5645 5646 5647 5648 5649 5650 | assert( pMain==0 || pMain==sqlite3_vfs_find(0) ); /* We can find a VFS by its name */ assert( sqlite3_vfs_find("__one")==&one ); assert( sqlite3_vfs_find("__two")==&two ); /* Calling sqlite_vfs_register with non-zero second parameter changes the | | | 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 | assert( pMain==0 || pMain==sqlite3_vfs_find(0) ); /* We can find a VFS by its name */ assert( sqlite3_vfs_find("__one")==&one ); assert( sqlite3_vfs_find("__two")==&two ); /* Calling sqlite_vfs_register with non-zero second parameter changes the ** default VFS, even if the 1st parameter is an existing VFS that is ** previously registered as the non-default. */ sqlite3_vfs_register(&one, 1); assert( sqlite3_vfs_find("__one")==&one ); assert( sqlite3_vfs_find("__two")==&two ); assert( sqlite3_vfs_find(0)==&one ); sqlite3_vfs_register(&two, 1); |
︙ | ︙ | |||
6970 6971 6972 6973 6974 6975 6976 | } #endif #if SQLITE_OS_WIN /* ** lock_win32_file FILENAME DELAY1 DELAY2 ** | | | 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 | } #endif #if SQLITE_OS_WIN /* ** lock_win32_file FILENAME DELAY1 DELAY2 ** ** Get an exclusive mandatory lock on file for DELAY2 milliseconds. ** Wait DELAY1 milliseconds before acquiring the lock. */ static int SQLITE_TCLAPI win32_file_lock( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] |
︙ | ︙ |
Changes to src/test_init.c.
︙ | ︙ | |||
34 35 36 37 38 39 40 | #endif static struct Wrapped { sqlite3_pcache_methods2 pcache; sqlite3_mem_methods mem; sqlite3_mutex_methods mutex; | | | | | | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #endif static struct Wrapped { sqlite3_pcache_methods2 pcache; sqlite3_mem_methods mem; sqlite3_mutex_methods mutex; int mem_init; /* True if mem subsystem is initialized */ int mem_fail; /* True to fail mem subsystem initalization */ int mutex_init; /* True if mutex subsystem is initialized */ int mutex_fail; /* True to fail mutex subsystem initalization */ int pcache_init; /* True if pcache subsystem is initialized */ int pcache_fail; /* True to fail pcache subsystem initalization */ } wrapped; static int wrMemInit(void *pAppData){ int rc; if( wrapped.mem_fail ){ rc = SQLITE_ERROR; }else{ |
︙ | ︙ |
Changes to src/test_intarray.h.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** ** The intarray virtual table is designed to facilitate using an ** array of integers as the right-hand side of an IN operator. So ** instead of doing a prepared statement like this: ** ** SELECT * FROM table WHERE x IN (?,?,?,...,?); ** | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** ** The intarray virtual table is designed to facilitate using an ** array of integers as the right-hand side of an IN operator. So ** instead of doing a prepared statement like this: ** ** SELECT * FROM table WHERE x IN (?,?,?,...,?); ** ** And then binding individual integers to each of ? slots, a C-language ** application can create an intarray object (named "ex1" in the following ** example), prepare a statement like this: ** ** SELECT * FROM table WHERE x IN ex1; ** ** Then bind an ordinary C/C++ array of integer values to the ex1 object ** to run the statement. |
︙ | ︙ |
Changes to src/test_multiplex.c.
︙ | ︙ | |||
347 348 349 350 351 352 353 | } } return pSubOpen; } /* ** Return the size, in bytes, of chunk number iChunk. If that chunk | | | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | } } return pSubOpen; } /* ** Return the size, in bytes, of chunk number iChunk. If that chunk ** does not exist, then return 0. This function does not distinguish between ** non-existant files and zero-length files. */ static sqlite3_int64 multiplexSubSize( multiplexGroup *pGroup, /* The multiplexor group */ int iChunk, /* Which chunk to open. 0==original file */ int *rc /* Result code in and out */ ){ |
︙ | ︙ | |||
570 571 572 573 574 575 576 | /* If the first overflow file exists and if the size of the main file ** is different from the chunk size, that means the chunk size is set ** set incorrectly. So fix it. ** ** Or, if the first overflow file does not exist and the main file is ** larger than the chunk size, that means the chunk size is too small. ** But we have no way of determining the intended chunk size, so | | | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | /* If the first overflow file exists and if the size of the main file ** is different from the chunk size, that means the chunk size is set ** set incorrectly. So fix it. ** ** Or, if the first overflow file does not exist and the main file is ** larger than the chunk size, that means the chunk size is too small. ** But we have no way of determining the intended chunk size, so ** just disable the multiplexor all together. */ rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z, SQLITE_ACCESS_EXISTS, &bExists); bExists = multiplexSubSize(pGroup, 1, &rc)>0; if( rc==SQLITE_OK && bExists && sz64==(sz64&0xffff0000) && sz64>0 && sz64!=pGroup->szChunk ){ pGroup->szChunk = (int)sz64; |
︙ | ︙ |
Changes to src/test_mutex.c.
︙ | ︙ | |||
41 42 43 44 45 46 47 | sqlite3_mutex *pReal; int eType; }; /* State variables */ static struct test_mutex_globals { int isInstalled; /* True if installed */ | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | sqlite3_mutex *pReal; int eType; }; /* State variables */ static struct test_mutex_globals { int isInstalled; /* True if installed */ int disableInit; /* True to cause sqlite3_initialize() to fail */ int disableTry; /* True to force sqlite3_mutex_try() to fail */ int isInit; /* True if initialized */ sqlite3_mutex_methods m; /* Interface to "real" mutex system */ int aCounter[MAX_MUTEXES]; /* Number of grabs of each type of mutex */ sqlite3_mutex aStatic[STATIC_MUTEXES]; /* The static mutexes */ } g = {0}; |
︙ | ︙ |
Changes to src/test_pcache.c.
︙ | ︙ | |||
32 33 34 35 36 37 38 | */ typedef struct testpcacheGlobalType testpcacheGlobalType; struct testpcacheGlobalType { void *pDummy; /* Dummy allocation to simulate failures */ int nInstance; /* Number of current instances */ unsigned discardChance; /* Chance of discarding on an unpin (0-100) */ unsigned prngSeed; /* Seed for the PRNG */ | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | */ typedef struct testpcacheGlobalType testpcacheGlobalType; struct testpcacheGlobalType { void *pDummy; /* Dummy allocation to simulate failures */ int nInstance; /* Number of current instances */ unsigned discardChance; /* Chance of discarding on an unpin (0-100) */ unsigned prngSeed; /* Seed for the PRNG */ unsigned highStress; /* Call xStress aggressively */ }; static testpcacheGlobalType testpcacheGlobal; /* ** Initializer. ** ** Verify that the initializer is only called when the system is |
︙ | ︙ | |||
424 425 426 427 428 429 430 | ** page. 0 means never discard (unless the discard flag is set). ** 100 means always discard. */ void installTestPCache( int installFlag, /* True to install. False to uninstall. */ unsigned discardChance, /* 0-100. Chance to discard on unpin */ unsigned prngSeed, /* Seed for the PRNG */ | | | 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | ** page. 0 means never discard (unless the discard flag is set). ** 100 means always discard. */ void installTestPCache( int installFlag, /* True to install. False to uninstall. */ unsigned discardChance, /* 0-100. Chance to discard on unpin */ unsigned prngSeed, /* Seed for the PRNG */ unsigned highStress /* Call xStress aggressively */ ){ static const sqlite3_pcache_methods2 testPcache = { 1, (void*)&testpcacheGlobal, testpcacheInit, testpcacheShutdown, testpcacheCreate, |
︙ | ︙ |
Changes to src/test_quota.c.
︙ | ︙ | |||
995 996 997 998 999 1000 1001 | ** Write content into a quota_FILE. Invoke the quota callback and block ** the write if we exceed quota. */ size_t sqlite3_quota_fwrite( const void *pBuf, /* Take content to write from here */ size_t size, /* Size of each element */ size_t nmemb, /* Number of elements */ | | | 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 | ** Write content into a quota_FILE. Invoke the quota callback and block ** the write if we exceed quota. */ size_t sqlite3_quota_fwrite( const void *pBuf, /* Take content to write from here */ size_t size, /* Size of each element */ size_t nmemb, /* Number of elements */ quota_FILE *p /* Write to this quota_FILE object */ ){ sqlite3_int64 iOfst; sqlite3_int64 iEnd; sqlite3_int64 szNew; quotaFile *pFile; size_t rc; |
︙ | ︙ | |||
1872 1873 1874 1875 1876 1877 1878 | static int SQLITE_TCLAPI test_quota_glob( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ const char *zPattern; /* The glob pattern */ | | | 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 | static int SQLITE_TCLAPI test_quota_glob( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ const char *zPattern; /* The glob pattern */ const char *zText; /* Text to compare against the pattern */ int rc; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "PATTERN TEXT"); return TCL_ERROR; } zPattern = Tcl_GetString(objv[1]); zText = Tcl_GetString(objv[2]); |
︙ | ︙ |
Changes to src/test_server.c.
︙ | ︙ | |||
145 146 147 148 149 150 151 | **** Restrictions Associated With SQLITE_ENABLE_MEMORY_MANAGEMENT **** ** ** If you compile with SQLITE_ENABLE_MEMORY_MANAGEMENT defined, then ** SQLite includes code that tracks how much memory is being used by ** each thread. These memory counts can become confused if memory ** is allocated by one thread and then freed by another. For that ** reason, when SQLITE_ENABLE_MEMORY_MANAGEMENT is used, all operations | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | **** Restrictions Associated With SQLITE_ENABLE_MEMORY_MANAGEMENT **** ** ** If you compile with SQLITE_ENABLE_MEMORY_MANAGEMENT defined, then ** SQLite includes code that tracks how much memory is being used by ** each thread. These memory counts can become confused if memory ** is allocated by one thread and then freed by another. For that ** reason, when SQLITE_ENABLE_MEMORY_MANAGEMENT is used, all operations ** that might allocate or free memory should be performed in the same ** thread that originally created the database connection. In that case, ** many of the operations that are listed above as safe to be performed ** in separate threads would need to be sent over to the server to be ** done there. If SQLITE_ENABLE_MEMORY_MANAGEMENT is defined, then ** the following functions can be used safely from different threads ** without messing up the allocation counts: ** |
︙ | ︙ | |||
455 456 457 458 459 460 461 | } pthread_mutex_unlock(&g.serverMutex); return 0; } /* ** Start a server thread if one is not already running. If there | | | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | } pthread_mutex_unlock(&g.serverMutex); return 0; } /* ** Start a server thread if one is not already running. If there ** is already a server thread running, the new thread will quickly ** die and this routine is effectively a no-op. */ void sqlite3_server_start(void){ pthread_t x; int rc; g.serverHalt = 0; rc = pthread_create(&x, 0, sqlite3_server, 0); |
︙ | ︙ |
Changes to src/test_superlock.c.
︙ | ︙ | |||
87 88 89 90 91 92 93 | ** of the file fd. If the lock cannot be obtained immediately, invoke ** the busy-handler until either it is obtained or the busy-handler ** callback returns 0. */ static int superlockShmLock( sqlite3_file *fd, /* Database file handle */ int idx, /* Offset of shm-lock to obtain */ | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | ** of the file fd. If the lock cannot be obtained immediately, invoke ** the busy-handler until either it is obtained or the busy-handler ** callback returns 0. */ static int superlockShmLock( sqlite3_file *fd, /* Database file handle */ int idx, /* Offset of shm-lock to obtain */ int nByte, /* Number of consecutive bytes to lock */ SuperlockBusy *pBusy /* Busy-handler wrapper object */ ){ int rc; int (*xShmLock)(sqlite3_file*, int, int, int) = fd->pMethods->xShmLock; do { rc = xShmLock(fd, idx, nByte, SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE); }while( rc==SQLITE_BUSY && superlockBusyHandler((void *)pBusy, 0) ); |
︙ | ︙ |
Changes to src/test_windirent.h.
︙ | ︙ | |||
136 137 138 139 140 141 142 | */ #ifndef is_filtered # define is_filtered(a) ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM)) #endif /* | | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | */ #ifndef is_filtered # define is_filtered(a) ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM)) #endif /* ** Provide the function prototype for the POSIX compatible getenv() ** function. This function is not thread-safe. */ extern const char *windirent_getenv(const char *name); /* ** Finally, we can provide the function prototypes for the opendir(), |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
1273 1274 1275 1276 1277 1278 1279 | if( eOnePass==ONEPASS_OFF ){ /* End the virtual table scan */ if( pSrc->nSrc==1 ){ sqlite3WhereEnd(pWInfo); } | | | 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 | if( eOnePass==ONEPASS_OFF ){ /* End the virtual table scan */ if( pSrc->nSrc==1 ){ sqlite3WhereEnd(pWInfo); } /* Begin scanning through the ephemeral table. */ addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v); /* Extract arguments from the current row of the ephemeral table and ** invoke the VUpdate method. */ for(i=0; i<nArg; i++){ sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i, regArg+i); } |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
30 31 32 33 34 35 36 | dummy += (unsigned)x; } #endif /* ** Calls to sqlite3FaultSim() are used to simulate a failure during testing, ** or to bypass normal error detection during testing in order to let | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | dummy += (unsigned)x; } #endif /* ** Calls to sqlite3FaultSim() are used to simulate a failure during testing, ** or to bypass normal error detection during testing in order to let ** execute proceed further downstream. ** ** In deployment, sqlite3FaultSim() *always* return SQLITE_OK (0). The ** sqlite3FaultSim() function only returns non-zero during testing. ** ** During testing, if the test harness has set a fault-sim callback using ** a call to sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL), then ** each call to sqlite3FaultSim() is relayed to that application-supplied |
︙ | ︙ | |||
575 576 577 578 579 580 581 | } } } /* store the result */ *pResult = result; | | | 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 | } } } /* store the result */ *pResult = result; /* return true if number and no extra non-whitespace characters after */ if( z==zEnd && nDigit>0 && eValid && eType>0 ){ return eType; }else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){ return -1; }else{ return 0; } |
︙ | ︙ | |||
601 602 603 604 605 606 607 | ** The caller must ensure that zOut[] is at least 21 bytes in size. */ void sqlite3Int64ToText(i64 v, char *zOut){ int i; u64 x; char zTemp[22]; if( v<0 ){ | | | 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 | ** The caller must ensure that zOut[] is at least 21 bytes in size. */ void sqlite3Int64ToText(i64 v, char *zOut){ int i; u64 x; char zTemp[22]; if( v<0 ){ x = (v==SMALLEST_INT64) ? ((u64)1)<<63 : (u64)-v; }else{ x = v; } i = sizeof(zTemp)-2; zTemp[sizeof(zTemp)-1] = 0; do{ zTemp[i--] = (x%10) + '0'; |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
863 864 865 866 867 868 869 | ** is sometimes set to 1 instead of 0 as a hint to the command-line shell ** that this Goto is the bottom of a loop and that the lines from P2 down ** to the current line should be indented for EXPLAIN output. */ case OP_Goto: { /* jump */ #ifdef SQLITE_DEBUG | | | 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | ** is sometimes set to 1 instead of 0 as a hint to the command-line shell ** that this Goto is the bottom of a loop and that the lines from P2 down ** to the current line should be indented for EXPLAIN output. */ case OP_Goto: { /* jump */ #ifdef SQLITE_DEBUG /* In debugging mode, when the p5 flags is set on an OP_Goto, that ** means we should really jump back to the preceeding OP_ReleaseReg ** instruction. */ if( pOp->p5 ){ assert( pOp->p2 < (int)(pOp - aOp) ); assert( pOp->p2 > 1 ); pOp = &aOp[pOp->p2 - 2]; assert( pOp[1].opcode==OP_ReleaseReg ); |
︙ | ︙ | |||
1049 1050 1051 1052 1053 1054 1055 | ** VDBE, but do not rollback the transaction. ** ** If P4 is not null then it is an error message string. ** ** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. ** ** 0: (no change) | | | 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | ** VDBE, but do not rollback the transaction. ** ** If P4 is not null then it is an error message string. ** ** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. ** ** 0: (no change) ** 1: NOT NULL constraint failed: P4 ** 2: UNIQUE constraint failed: P4 ** 3: CHECK constraint failed: P4 ** 4: FOREIGN KEY constraint failed: P4 ** ** If P5 is not zero and P4 is NULL, then everything after the ":" is ** omitted. ** |
︙ | ︙ | |||
3937 3938 3939 3940 3941 3942 3943 | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TRANSIENT_DB; assert( pOp->p1>=0 ); assert( pOp->p2>=0 ); pCx = p->apCsr[pOp->p1]; if( pCx && pCx->pBtx ){ | | | 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TRANSIENT_DB; assert( pOp->p1>=0 ); assert( pOp->p2>=0 ); pCx = p->apCsr[pOp->p1]; if( pCx && pCx->pBtx ){ /* If the ephemeral table is already open, erase all existing content ** so that the table is empty again, rather than creating a new table. */ assert( pCx->isEphemeral ); pCx->seqCount = 0; pCx->cacheStatus = CACHE_STALE; rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); }else{ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); |
︙ | ︙ | |||
5063 5064 5065 5066 5067 5068 5069 | zDb, pTab, pC->movetoTarget, pOp->p3 ); } if( opflags & OPFLAG_ISNOOP ) break; #endif | | | 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 | zDb, pTab, pC->movetoTarget, pOp->p3 ); } if( opflags & OPFLAG_ISNOOP ) break; #endif /* Only flags that can be set are SAVEPOSITION and AUXDELETE */ assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 ); assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION ); assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE ); #ifdef SQLITE_DEBUG if( p->pFrame==0 ){ if( pC->isEphemeral==0 |
︙ | ︙ | |||
6808 6809 6810 6811 6812 6813 6814 | pMem->uTemp = 0x1122e0e3; } #endif /* If this function is inside of a trigger, the register array in aMem[] ** might change from one evaluation to the next. The next block of code ** checks to see if the register array has changed, and if so it | | | 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 | pMem->uTemp = 0x1122e0e3; } #endif /* If this function is inside of a trigger, the register array in aMem[] ** might change from one evaluation to the next. The next block of code ** checks to see if the register array has changed, and if so it ** reinitializes the relevant parts of the sqlite3_context object */ if( pCtx->pMem != pMem ){ pCtx->pMem = pMem; for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; } #ifdef SQLITE_DEBUG for(i=0; i<pCtx->argc; i++){ |
︙ | ︙ | |||
7660 7661 7662 7663 7664 7665 7666 | ** whether meta data associated with a user function argument using the ** sqlite3_set_auxdata() API may be safely retained until the next ** invocation of this opcode. ** ** This opcode works exactly like OP_Function. The only difference is in ** its name. This opcode is used in places where the function must be ** purely non-deterministic. Some built-in date/time functions can be | | | | 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 | ** whether meta data associated with a user function argument using the ** sqlite3_set_auxdata() API may be safely retained until the next ** invocation of this opcode. ** ** This opcode works exactly like OP_Function. The only difference is in ** its name. This opcode is used in places where the function must be ** purely non-deterministic. Some built-in date/time functions can be ** either deterministic or non-deterministic, depending on their arguments. ** When those function are used in a non-deterministic way, they will check ** to see if they were called using OP_PureFunc instead of OP_Function, and ** if they were, they throw an error. ** ** See also: AggStep, AggFinal, Function */ case OP_PureFunc: /* group */ case OP_Function: { /* group */ int i; sqlite3_context *pCtx; assert( pOp->p4type==P4_FUNCCTX ); pCtx = pOp->p4.pCtx; /* If this function is inside of a trigger, the register array in aMem[] ** might change from one evaluation to the next. The next block of code ** checks to see if the register array has changed, and if so it ** reinitializes the relevant parts of the sqlite3_context object */ pOut = &aMem[pOp->p3]; if( pCtx->pOut != pOut ){ pCtx->pVdbe = p; pCtx->pOut = pOut; for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; } assert( pCtx->pVdbe==p ); |
︙ | ︙ | |||
7959 7960 7961 7962 7963 7964 7965 | registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]); } if( opProperty & OPFLG_OUT3 ){ registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); } if( opProperty==0xff ){ /* Never happens. This code exists to avoid a harmless linkage | | | 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 | registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]); } if( opProperty & OPFLG_OUT3 ){ registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); } if( opProperty==0xff ){ /* Never happens. This code exists to avoid a harmless linkage ** warning about sqlite3VdbeRegisterDump() being defined but not ** used. */ sqlite3VdbeRegisterDump(p); } } #endif /* SQLITE_DEBUG */ #endif /* NDEBUG */ } /* The end of the for(;;) loop the loops through opcodes */ |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
317 318 319 320 321 322 323 | # define VdbeModuleComment(X) #endif /* ** The VdbeCoverage macros are used to set a coverage testing point ** for VDBE branch instructions. The coverage testing points are line ** numbers in the sqlite3.c source file. VDBE branch coverage testing | | | | 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 | # define VdbeModuleComment(X) #endif /* ** The VdbeCoverage macros are used to set a coverage testing point ** for VDBE branch instructions. The coverage testing points are line ** numbers in the sqlite3.c source file. VDBE branch coverage testing ** only works with an amalgamation build. That's ok since a VDBE branch ** coverage build designed for testing the test suite only. No application ** should ever ship with VDBE branch coverage measuring turned on. ** ** VdbeCoverage(v) // Mark the previously coded instruction ** // as a branch ** ** VdbeCoverageIf(v, conditional) // Mark previous if conditional true ** ** VdbeCoverageAlwaysTaken(v) // Previous branch is always taken ** ** VdbeCoverageNeverTaken(v) // Previous branch is never taken ** ** VdbeCoverageNeverNull(v) // Previous three-way branch is only ** // taken on the first two ways. The ** // NULL option is not possible ** ** VdbeCoverageEqNe(v) // Previous OP_Jump is only interested ** // in distinguishing equal and not-equal. ** ** Every VDBE branch operation must be tagged with one of the macros above. ** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and ** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch() ** routine in vdbe.c, alerting the developer to the missed tag. ** ** During testing, the test application will invoke |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
1081 1082 1083 1084 1085 1086 1087 | ** sqlite3_column_int() ** sqlite3_column_int64() ** sqlite3_column_text() ** sqlite3_column_text16() ** sqlite3_column_real() ** sqlite3_column_bytes() ** sqlite3_column_bytes16() | | | 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 | ** sqlite3_column_int() ** sqlite3_column_int64() ** sqlite3_column_text() ** sqlite3_column_text16() ** sqlite3_column_real() ** sqlite3_column_bytes() ** sqlite3_column_bytes16() ** sqlite3_column_blob() */ static void columnMallocFailure(sqlite3_stmt *pStmt) { /* If malloc() failed during an encoding conversion within an ** sqlite3_column_XXX API, then set the return code of the statement to ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR ** and _finalize() will return NOMEM. |
︙ | ︙ | |||
1315 1316 1317 1318 1319 1320 1321 | /******************************* sqlite3_bind_ *************************** ** ** Routines used to attach values to wildcards in a compiled SQL statement. */ /* ** Unbind the value bound to variable i in virtual machine p. This is the ** the same as binding a NULL value to the column. If the "i" parameter is | | | 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 | /******************************* sqlite3_bind_ *************************** ** ** Routines used to attach values to wildcards in a compiled SQL statement. */ /* ** Unbind the value bound to variable i in virtual machine p. This is the ** the same as binding a NULL value to the column. If the "i" parameter is ** out of range, then SQLITE_RANGE is returned. Otherwise SQLITE_OK. ** ** A successful evaluation of this routine acquires the mutex on p. ** the mutex is released if any kind of error occurs. ** ** The error code stored in database p->db is overwritten with the return ** value in any case. */ |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
290 291 292 293 294 295 296 | int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){ return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0); } /* ** Generate code that initializes multiple registers to string or integer ** constants. The registers begin with iDest and increase consecutively. | | | 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){ return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0); } /* ** Generate code that initializes multiple registers to string or integer ** constants. The registers begin with iDest and increase consecutively. ** One register is initialized for each character in zTypes[]. For each ** "s" character in zTypes[], the register is a string if the argument is ** not NULL, or OP_Null if the value is a null pointer. For each "i" character ** in zTypes[], the register is initialized to an integer. ** ** If the input string does not end with "X" then an OP_ResultRow instruction ** is generated for the values inserted. */ |
︙ | ︙ | |||
1092 1093 1094 1095 1096 1097 1098 | sqlite3VdbeChangeP2(p, addr, p->nOp); } } /* ** If the input FuncDef structure is ephemeral, then free it. If | | | 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 | sqlite3VdbeChangeP2(p, addr, p->nOp); } } /* ** If the input FuncDef structure is ephemeral, then free it. If ** the FuncDef is not ephemeral, then do nothing. */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ sqlite3DbFreeNN(db, pDef); } } |
︙ | ︙ | |||
1976 1977 1978 1979 1980 1981 1982 | ** the sum of the number of rows in all trigger subprograms encountered ** so far. The nRow value will increase as new trigger subprograms are ** encountered, but p->pc will eventually catch up to nRow. */ nRow = p->nOp; if( pSub!=0 ){ if( pSub->flags&MEM_Blob ){ | | | 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 | ** the sum of the number of rows in all trigger subprograms encountered ** so far. The nRow value will increase as new trigger subprograms are ** encountered, but p->pc will eventually catch up to nRow. */ nRow = p->nOp; if( pSub!=0 ){ if( pSub->flags&MEM_Blob ){ /* pSub is initially NULL. It is initialized to a BLOB by ** the P4_SUBPROGRAM processing logic below */ nSub = pSub->n/sizeof(Vdbe*); apSub = (SubProgram **)pSub->z; } for(i=0; i<nSub; i++){ nRow += apSub[i]->nOp; } |
︙ | ︙ | |||
4545 4546 4547 4548 4549 4550 4551 | /* RHS is real */ else if( pRhs->flags & MEM_Real ){ serial_type = aKey1[idx1]; if( serial_type>=10 ){ /* Serial types 12 or greater are strings and blobs (greater than ** numbers). Types 10 and 11 are currently "reserved for future ** use", so it doesn't really matter what the results of comparing | | | 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 | /* RHS is real */ else if( pRhs->flags & MEM_Real ){ serial_type = aKey1[idx1]; if( serial_type>=10 ){ /* Serial types 12 or greater are strings and blobs (greater than ** numbers). Types 10 and 11 are currently "reserved for future ** use", so it doesn't really matter what the results of comparing ** them to numeric values are. */ rc = +1; }else if( serial_type==0 ){ rc = -1; }else{ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); if( serial_type==7 ){ if( mem1.u.r<pRhs->u.r ){ |
︙ | ︙ | |||
5014 5015 5016 5017 5018 5019 5020 | void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){ assert( sqlite3_mutex_held(db->mutex) ); db->nChange = nChange; db->nTotalChange += nChange; } /* | | | 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 | void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){ assert( sqlite3_mutex_held(db->mutex) ); db->nChange = nChange; db->nTotalChange += nChange; } /* ** Set a flag in the vdbe to update the change counter when it is finalized ** or reset. */ void sqlite3VdbeCountChanges(Vdbe *v){ v->changeCntOn = 1; } /* |
︙ | ︙ |
Changes to src/vdbesort.c.
︙ | ︙ | |||
81 82 83 84 85 86 87 | ** A PMA created at this point is known as a "level-0 PMA". Higher levels ** of PMAs may be created by merging existing PMAs together - for example ** merging two or more level-0 PMAs together creates a level-1 PMA. ** ** The threshold for the amount of main memory to use before flushing ** records to a PMA is roughly the same as the limit configured for the ** page-cache of the main database. Specifically, the threshold is set to | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | ** A PMA created at this point is known as a "level-0 PMA". Higher levels ** of PMAs may be created by merging existing PMAs together - for example ** merging two or more level-0 PMAs together creates a level-1 PMA. ** ** The threshold for the amount of main memory to use before flushing ** records to a PMA is roughly the same as the limit configured for the ** page-cache of the main database. Specifically, the threshold is set to ** the value returned by "PRAGMA main.page_size" multiplied by ** that returned by "PRAGMA main.cache_size", in bytes. ** ** If the sorter is running in single-threaded mode, then all PMAs generated ** are appended to a single temporary file. Or, if the sorter is running in ** multi-threaded mode then up to (N+1) temporary files may be opened, where ** N is the configured number of worker threads. In this case, instead of ** sorting the records and writing the PMA to a temporary file itself, the |
︙ | ︙ | |||
104 105 106 107 108 109 110 | ** ** When Rewind() is called, any data remaining in memory is flushed to a ** final PMA. So at this point the data is stored in some number of sorted ** PMAs within temporary files on disk. ** ** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the ** sorter is running in single-threaded mode, then these PMAs are merged | | | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | ** ** When Rewind() is called, any data remaining in memory is flushed to a ** final PMA. So at this point the data is stored in some number of sorted ** PMAs within temporary files on disk. ** ** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the ** sorter is running in single-threaded mode, then these PMAs are merged ** incrementally as keys are retrieved from the sorter by the VDBE. The ** MergeEngine object, described in further detail below, performs this ** merge. ** ** Or, if running in multi-threaded mode, then a background thread is ** launched to merge the existing PMAs. Once the background thread has ** merged T bytes of data into a single sorted PMA, the main thread ** begins reading keys from that PMA while the background thread proceeds |
︙ | ︙ | |||
267 268 269 270 271 272 273 | ** other way. VdbeSorter.nTask is set to the number of worker threads allowed ** (see SQLITE_CONFIG_WORKER_THREADS) plus one (the main thread). Thus for ** single-threaded operation, there is exactly one instance of this object ** and for multi-threaded operation there are two or more instances. ** ** Essentially, this structure contains all those fields of the VdbeSorter ** structure for which each thread requires a separate instance. For example, | | | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | ** other way. VdbeSorter.nTask is set to the number of worker threads allowed ** (see SQLITE_CONFIG_WORKER_THREADS) plus one (the main thread). Thus for ** single-threaded operation, there is exactly one instance of this object ** and for multi-threaded operation there are two or more instances. ** ** Essentially, this structure contains all those fields of the VdbeSorter ** structure for which each thread requires a separate instance. For example, ** each thread requires its own UnpackedRecord object to unpack records in ** as part of comparison operations. ** ** Before a background thread is launched, variable bDone is set to 0. Then, ** right before it exits, the thread itself sets bDone to 1. This is used for ** two purposes: ** ** 1. When flushing the contents of memory to a level-0 PMA on disk, to |
︙ | ︙ | |||
2188 2189 2190 2191 2192 2193 2194 | sqlite3 *db = pTask->pSorter->db; /* eMode is always INCRINIT_NORMAL in single-threaded mode */ assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); | | | 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 | sqlite3 *db = pTask->pSorter->db; /* eMode is always INCRINIT_NORMAL in single-threaded mode */ assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); /* Set up the required files for pIncr. A multi-threaded IncrMerge object ** requires two temp files to itself, whereas a single-threaded object ** only requires a region of pTask->file2. */ if( rc==SQLITE_OK ){ int mxSz = pIncr->mxSz; #if SQLITE_MAX_WORKER_THREADS>0 if( pIncr->bUseThread ){ rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd); |
︙ | ︙ |
Changes to src/vtab.c.
︙ | ︙ | |||
1190 1191 1192 1193 1194 1195 1196 | ** Check to see if virtual table module pMod can be have an eponymous ** virtual table instance. If it can, create one if one does not already ** exist. Return non-zero if the eponymous virtual table instance exists ** when this routine returns, and return zero if it does not exist. ** ** An eponymous virtual table instance is one that is named after its ** module, and more importantly, does not require a CREATE VIRTUAL TABLE | | | 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 | ** Check to see if virtual table module pMod can be have an eponymous ** virtual table instance. If it can, create one if one does not already ** exist. Return non-zero if the eponymous virtual table instance exists ** when this routine returns, and return zero if it does not exist. ** ** An eponymous virtual table instance is one that is named after its ** module, and more importantly, does not require a CREATE VIRTUAL TABLE ** statement in order to come into existence. Eponymous virtual table ** instances always exist. They cannot be DROP-ed. ** ** Any virtual table module for which xConnect and xCreate are the same ** method can have an eponymous virtual table instance. */ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ const sqlite3_module *pModule = pMod->pModule; |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
277 278 279 280 281 282 283 | /* ** Index numbers for various locking bytes. WAL_NREADER is the number ** of available reader locks and should be at least 3. The default ** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5. ** ** Technically, the various VFSes are free to implement these locks however ** they see fit. However, compatibility is encouraged so that VFSes can | | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | /* ** Index numbers for various locking bytes. WAL_NREADER is the number ** of available reader locks and should be at least 3. The default ** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5. ** ** Technically, the various VFSes are free to implement these locks however ** they see fit. However, compatibility is encouraged so that VFSes can ** interoperate. The standard implementation used on both unix and windows ** is for the index number to indicate a byte offset into the ** WalCkptInfo.aLock[] array in the wal-index header. In other words, all ** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which ** should be 120) is the location in the shm file for the first locking ** byte. */ #define WAL_WRITE_LOCK 0 |
︙ | ︙ | |||
339 340 341 342 343 344 345 | ** database "backfilling".) The nBackfill number is never greater than ** WalIndexHdr.mxFrame. nBackfill can only be increased by threads ** holding the WAL_CKPT_LOCK lock (which includes a recovery thread). ** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from ** mxFrame back to zero when the WAL is reset. ** ** nBackfillAttempted is the largest value of nBackfill that a checkpoint | | | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | ** database "backfilling".) The nBackfill number is never greater than ** WalIndexHdr.mxFrame. nBackfill can only be increased by threads ** holding the WAL_CKPT_LOCK lock (which includes a recovery thread). ** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from ** mxFrame back to zero when the WAL is reset. ** ** nBackfillAttempted is the largest value of nBackfill that a checkpoint ** has attempted to achieve. Normally nBackfill==nBackfillAttempted, however ** the nBackfillAttempted is set before any backfilling is done and the ** nBackfill is only set after all backfilling completes. So if a checkpoint ** crashes, nBackfillAttempted might be larger than nBackfill. The ** WalIndexHdr.mxFrame must never be less than nBackfillAttempted. ** ** The aLock[] field is a set of bytes used for locking. These bytes should ** never be read or written. |
︙ | ︙ | |||
792 793 794 795 796 797 798 | /* A frame is only valid if the salt values in the frame-header ** match the salt values in the wal-header. */ if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){ return 0; } | | | | 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 | /* A frame is only valid if the salt values in the frame-header ** match the salt values in the wal-header. */ if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){ return 0; } /* A frame is only valid if the page number is greater than zero. */ pgno = sqlite3Get4byte(&aFrame[0]); if( pgno==0 ){ return 0; } /* A frame is only valid if a checksum of the WAL header, ** all prior frames, the first 16 bytes of this frame-header, ** and the frame-data matches the checksum in the last 8 ** bytes of this frame-header. */ nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) |
︙ | ︙ | |||
1436 1437 1438 1439 1440 1441 1442 | *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); } return rc; } /* | | | 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 | *ppWal = pRet; WALTRACE(("WAL%d: opened\n", pRet)); } return rc; } /* ** Change the size to which the WAL file is truncated on each reset. */ void sqlite3WalLimit(Wal *pWal, i64 iLimit){ if( pWal ) pWal->mxWalSize = iLimit; } /* ** Find the smallest page number out of all pages held in the WAL that |
︙ | ︙ | |||
1630 1631 1632 1633 1634 1635 1636 | ** Free an iterator allocated by walIteratorInit(). */ static void walIteratorFree(WalIterator *p){ sqlite3_free(p); } /* | | | | 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 | ** Free an iterator allocated by walIteratorInit(). */ static void walIteratorFree(WalIterator *p){ sqlite3_free(p); } /* ** Construct a WalIterator object that can be used to loop over all ** pages in the WAL following frame nBackfill in ascending order. Frames ** nBackfill or earlier may be included - excluding them is an optimization ** only. The caller must hold the checkpoint lock. ** ** On success, make *pp point to the newly allocated WalIterator object ** return SQLITE_OK. Otherwise, return an error code. If this routine ** returns an error, the value of *pp is undefined. ** ** The calling routine should invoke walIteratorFree() to destroy the ** WalIterator object when it has finished with it. */ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ |
︙ | ︙ | |||
2195 2196 2197 2198 2199 2200 2201 | ** There are two copies of the header at the beginning of the wal-index. ** When reading, read [0] first then [1]. Writes are in the reverse order. ** Memory barriers are used to prevent the compiler or the hardware from ** reordering the reads and writes. TSAN and similar tools can sometimes ** give false-positive warnings about these accesses because the tools do not ** account for the double-read and the memory barrier. The use of mutexes ** here would be problematic as the memory being accessed is potentially | | | 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 | ** There are two copies of the header at the beginning of the wal-index. ** When reading, read [0] first then [1]. Writes are in the reverse order. ** Memory barriers are used to prevent the compiler or the hardware from ** reordering the reads and writes. TSAN and similar tools can sometimes ** give false-positive warnings about these accesses because the tools do not ** account for the double-read and the memory barrier. The use of mutexes ** here would be problematic as the memory being accessed is potentially ** shared among multiple processes and not all mutex implementations work ** reliably in that environment. */ aHdr = walIndexHdr(pWal); memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); /* Possible TSAN false-positive */ walShmBarrier(pWal); memcpy(&h2, (void *)&aHdr[1], sizeof(h2)); |
︙ | ︙ |
Changes to src/walker.c.
︙ | ︙ | |||
205 206 207 208 209 210 211 | } p = p->pPrior; }while( p!=0 ); return WRC_Continue; } /* Increase the walkerDepth when entering a subquery, and | | | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | } p = p->pPrior; }while( p!=0 ); return WRC_Continue; } /* Increase the walkerDepth when entering a subquery, and ** decrease when leaving the subquery. */ int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){ UNUSED_PARAMETER(pSelect); pWalker->walkerDepth++; return WRC_Continue; } void sqlite3WalkerDepthDecrease(Walker *pWalker, Select *pSelect){ |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
1320 1321 1322 1323 1324 1325 1326 | ** ** CREATE INDEX i1 ON t1(a, b, c); ** SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?; ** ** Value pLoop->nOut is currently set to the estimated number of rows ** visited for scanning (a=? AND b=?). This function reduces that estimate ** by some factor to account for the (c BETWEEN ? AND ?) expression based | | | 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 | ** ** CREATE INDEX i1 ON t1(a, b, c); ** SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?; ** ** Value pLoop->nOut is currently set to the estimated number of rows ** visited for scanning (a=? AND b=?). This function reduces that estimate ** by some factor to account for the (c BETWEEN ? AND ?) expression based ** on the stat4 data for the index. this scan will be performed multiple ** times (once for each (a,b) combination that matches a=?) is dealt with ** by the caller. ** ** It does this by scanning through all stat4 samples, comparing values ** extracted from pLower and pUpper with the corresponding column in each ** sample. If L and U are the number of samples found to be less than or ** equal to the values extracted from pLower and pUpper respectively, and |
︙ | ︙ | |||
2065 2066 2067 2068 2069 2070 2071 | || p->rSetup==pTemplate->rSetup ); /* whereLoopAddBtree() always generates and inserts the automatic index ** case first. Hence compatible candidate WhereLoops never have a larger ** rSetup. Call this SETUP-INVARIANT */ assert( p->rSetup>=pTemplate->rSetup ); | | | 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 | || p->rSetup==pTemplate->rSetup ); /* whereLoopAddBtree() always generates and inserts the automatic index ** case first. Hence compatible candidate WhereLoops never have a larger ** rSetup. Call this SETUP-INVARIANT */ assert( p->rSetup>=pTemplate->rSetup ); /* Any loop using an application-defined index (or PRIMARY KEY or ** UNIQUE constraint) with one or more == constraints is better ** than an automatic index. Unless it is a skip-scan. */ if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && (pTemplate->nSkip)==0 && (pTemplate->wsFlags & WHERE_INDEXED)!=0 && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0 && (p->prereq & pTemplate->prereq)==pTemplate->prereq |
︙ | ︙ | |||
2210 2211 2212 2213 2214 2215 2216 | *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop)); if( p==0 ) return SQLITE_NOMEM_BKPT; whereLoopInit(p); p->pNextLoop = 0; }else{ /* We will be overwriting WhereLoop p[]. But before we do, first ** go through the rest of the list and delete any other entries besides | | | 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 | *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop)); if( p==0 ) return SQLITE_NOMEM_BKPT; whereLoopInit(p); p->pNextLoop = 0; }else{ /* We will be overwriting WhereLoop p[]. But before we do, first ** go through the rest of the list and delete any other entries besides ** p[] that are also to be replaced by pTemplate */ WhereLoop **ppTail = &p->pNextLoop; WhereLoop *pToDel; while( *ppTail ){ ppTail = whereLoopFindLesser(ppTail, pTemplate); if( ppTail==0 ) break; pToDel = *ppTail; if( pToDel==0 ) break; |
︙ | ︙ | |||
2387 2388 2389 2390 2391 2392 2393 | if( pColl==0 ) break; if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; } return i; } /* | | | 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 | if( pColl==0 ) break; if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; } return i; } /* ** Adjust the cost C by the costMult factor T. This only occurs if ** compiled with -DSQLITE_ENABLE_COSTMULT */ #ifdef SQLITE_ENABLE_COSTMULT # define ApplyCostMultiplier(C,T) C += T #else # define ApplyCostMultiplier(C,T) #endif |
︙ | ︙ | |||
2595 2596 2597 2598 2599 2600 2601 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; pNew->u.btree.nBtm = whereRangeVectorLen( pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm ); pBtm = pTerm; pTop = 0; if( pTerm->wtFlags & TERM_LIKEOPT ){ | | | 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; pNew->u.btree.nBtm = whereRangeVectorLen( pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm ); pBtm = pTerm; pTop = 0; if( pTerm->wtFlags & TERM_LIKEOPT ){ /* Range constraints that come from the LIKE optimization are ** always used in pairs. */ pTop = &pTerm[1]; assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm ); assert( pTop->wtFlags & TERM_LIKEOPT ); assert( pTop->eOperator==WO_LT ); if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ pNew->aLTerm[pNew->nLTerm++] = pTop; |
︙ | ︙ | |||
2891 2892 2893 2894 2895 2896 2897 | ** log(nRow) factor is omitted from a non-covering index scan in order to ** bias the scoring in favor of using an index, since the worst-case ** performance of using an index is far better than the worst-case performance ** of a full table scan. */ static int whereLoopAddBtree( WhereLoopBuilder *pBuilder, /* WHERE clause information */ | | | 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 | ** log(nRow) factor is omitted from a non-covering index scan in order to ** bias the scoring in favor of using an index, since the worst-case ** performance of using an index is far better than the worst-case performance ** of a full table scan. */ static int whereLoopAddBtree( WhereLoopBuilder *pBuilder, /* WHERE clause information */ Bitmask mPrereq /* Extra prerequisites for using this table */ ){ WhereInfo *pWInfo; /* WHERE analysis context */ Index *pProbe; /* An index we are evaluating */ Index sPk; /* A fake index object for the primary key */ LogEst aiRowEstPk[2]; /* The aiRowLogEst[] value for the sPk index */ i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */ SrcList *pTabList; /* The FROM clause */ |
︙ | ︙ | |||
4207 4208 4209 4210 4211 4212 4213 | if( isOrdered>=0 && isOrdered<nOrderBy ){ if( aSortCost[isOrdered]==0 ){ aSortCost[isOrdered] = whereSortingCost( pWInfo, nRowEst, nOrderBy, isOrdered ); } /* TUNING: Add a small extra penalty (5) to sorting as an | | | 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 | if( isOrdered>=0 && isOrdered<nOrderBy ){ if( aSortCost[isOrdered]==0 ){ aSortCost[isOrdered] = whereSortingCost( pWInfo, nRowEst, nOrderBy, isOrdered ); } /* TUNING: Add a small extra penalty (5) to sorting as an ** extra encouragement to the query planner to select a plan ** where the rows emerge in the correct order without any sorting ** required. */ rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5; WHERETRACE(0x002, ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", aSortCost[isOrdered], (nOrderBy-isOrdered), nOrderBy, |
︙ | ︙ | |||
4653 4654 4655 4656 4657 4658 4659 | ** terms of the WHERE clause that use only terms in that loop and outer ** loops are evaluated and if false a jump is made around all subsequent ** inner loops (or around the "..." if the test occurs within the inner- ** most loop) ** ** OUTER JOINS ** | | | 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 | ** terms of the WHERE clause that use only terms in that loop and outer ** loops are evaluated and if false a jump is made around all subsequent ** inner loops (or around the "..." if the test occurs within the inner- ** most loop) ** ** OUTER JOINS ** ** An outer join of tables t1 and t2 is conceptually coded as follows: ** ** foreach row1 in t1 do ** flag = 0 ** foreach row2 in t2 do ** start: ** ... ** flag = 1 |
︙ | ︙ | |||
4806 4807 4808 4809 4810 4811 4812 | } ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); }else{ /* Assign a bit from the bitmask to every term in the FROM clause. ** ** The N-th term of the FROM clause is assigned a bitmask of 1<<N. ** | | | 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 | } ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); }else{ /* Assign a bit from the bitmask to every term in the FROM clause. ** ** The N-th term of the FROM clause is assigned a bitmask of 1<<N. ** ** The rule of the previous sentence ensures that if X is the bitmask for ** a table T, then X-1 is the bitmask for all other tables to the left of T. ** Knowing the bitmask for all tables to the left of a left join is ** important. Ticket #3015. ** ** Note that bitmasks are created for all pTabList->nSrc tables in ** pTabList, not just the first nTabList tables. nTabList is normally ** equal to pTabList->nSrc but might be shortened to 1 if the |
︙ | ︙ |
Changes to src/whereInt.h.
︙ | ︙ | |||
412 413 414 415 416 417 418 | int nRecValid; /* Number of valid fields currently in pRec */ #endif unsigned char bldFlags1; /* First set of SQLITE_BLDF_* flags */ unsigned char bldFlags2; /* Second set of SQLITE_BLDF_* flags */ unsigned int iPlanLimit; /* Search limiter */ }; | | | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 | int nRecValid; /* Number of valid fields currently in pRec */ #endif unsigned char bldFlags1; /* First set of SQLITE_BLDF_* flags */ unsigned char bldFlags2; /* Second set of SQLITE_BLDF_* flags */ unsigned int iPlanLimit; /* Search limiter */ }; /* Allowed values for WhereLoopBuilder.bldFlags */ #define SQLITE_BLDF1_INDEXED 0x0001 /* An index is used */ #define SQLITE_BLDF1_UNIQUE 0x0002 /* All keys of a UNIQUE index used */ #define SQLITE_BLDF2_2NDPASS 0x0004 /* Second builder pass needed */ /* The WhereLoopBuilder.iPlanLimit is used to limit the number of ** index+constraint combinations the query planner will consider for a |
︙ | ︙ |
Changes to src/wherecode.c.
︙ | ︙ | |||
872 873 874 875 876 877 878 | ** ** 1) allocate a register and code an OP_Column instruction to read ** the specified column into the new register, and ** ** 2) transform the expression node to a TK_REGISTER node that reads ** from the newly populated register. ** | | | 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 | ** ** 1) allocate a register and code an OP_Column instruction to read ** the specified column into the new register, and ** ** 2) transform the expression node to a TK_REGISTER node that reads ** from the newly populated register. ** ** Also, if the node is a TK_COLUMN that does access the table identified ** by pCCurHint.iTabCur, and an index is being used (which we will ** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into ** an access of the index rather than the original table. */ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ int rc = WRC_Continue; struct CCurHint *pHint = pWalker->u.pCCurHint; |
︙ | ︙ | |||
1508 1509 1510 1511 1512 1513 1514 | /* TK_GT */ OP_SeekGT, /* TK_LE */ OP_SeekLE, /* TK_LT */ OP_SeekLT, /* TK_GE */ OP_SeekGE }; assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ | | | 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 | /* TK_GT */ OP_SeekGT, /* TK_LE */ OP_SeekLE, /* TK_LT */ OP_SeekLT, /* TK_GE */ OP_SeekGE }; assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ assert( TK_GE==TK_GT+3 ); /* ... is correct. */ assert( (pStart->wtFlags & TERM_VNULL)==0 ); testcase( pStart->wtFlags & TERM_VIRTUAL ); pX = pStart->pExpr; assert( pX!=0 ); testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ if( sqlite3ExprIsVector(pX->pRight) ){ |
︙ | ︙ |
Changes to src/whereexpr.c.
︙ | ︙ | |||
160 161 162 163 164 165 166 | #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION /* ** Check to see if the given expression is a LIKE or GLOB operator that ** can be optimized using inequality constraints. Return TRUE if it is ** so and false if not. ** | | | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION /* ** Check to see if the given expression is a LIKE or GLOB operator that ** can be optimized using inequality constraints. Return TRUE if it is ** so and false if not. ** ** In order for the operator to be optimizable, the RHS must be a string ** literal that does not begin with a wildcard. The LHS must be a column ** that may only be NULL, a string, or a BLOB, never a number. (This means ** that virtual tables cannot participate in the LIKE optimization.) The ** collating sequence for the column on the LHS must be appropriate for ** the operator. */ static int isLikeOrGlob( |
︙ | ︙ | |||
787 788 789 790 791 792 793 | assert( j==1 ); continue; } if( (chngToIN & sqlite3WhereGetMask(&pWInfo->sMaskSet, pOrTerm->leftCursor))==0 ){ /* This term must be of the form t1.a==t2.b where t2 is in the ** chngToIN set but t1 is not. This term will be either preceded | | | 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 | assert( j==1 ); continue; } if( (chngToIN & sqlite3WhereGetMask(&pWInfo->sMaskSet, pOrTerm->leftCursor))==0 ){ /* This term must be of the form t1.a==t2.b where t2 is in the ** chngToIN set but t1 is not. This term will be either preceded ** or followed by an inverted copy (t2.b==t1.a). Skip this term ** and use its inversion. */ testcase( pOrTerm->wtFlags & TERM_COPIED ); testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); continue; } iColumn = pOrTerm->u.leftColumn; |
︙ | ︙ |
Changes to src/window.c.
︙ | ︙ | |||
113 114 115 116 117 118 119 | ** lag(expr [, offset [, default]]) ** first_value(expr) ** last_value(expr) ** nth_value(expr, N) ** ** These are the same built-in window functions supported by Postgres. ** Although the behaviour of aggregate window functions (functions that | | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | ** lag(expr [, offset [, default]]) ** first_value(expr) ** last_value(expr) ** nth_value(expr, N) ** ** These are the same built-in window functions supported by Postgres. ** Although the behaviour of aggregate window functions (functions that ** can be used as either aggregates or window functions) allows them to ** be implemented using an API, built-in window functions are much more ** esoteric. Additionally, some window functions (e.g. nth_value()) ** may only be implemented by caching the entire partition in memory. ** As such, some built-in window functions use the same API as aggregate ** window functions and some are implemented directly using VDBE ** instructions. Additionally, for those functions that use the API, the ** window frame is sometimes modified before the SELECT statement is |
︙ | ︙ | |||
1236 1237 1238 1239 1240 1241 1242 | sqlite3ExprListDelete(pParse->db, pPartition); sqlite3ExprListDelete(pParse->db, pOrderBy); } return pWin; } /* | | | 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 | sqlite3ExprListDelete(pParse->db, pPartition); sqlite3ExprListDelete(pParse->db, pOrderBy); } return pWin; } /* ** Window *pWin has just been created from a WINDOW clause. Token pBase ** is the base window. Earlier windows from the same WINDOW clause are ** stored in the linked list starting at pWin->pNextWin. This function ** either updates *pWin according to the base specification, or else ** leaves an error in pParse. */ void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){ if( pWin->zBase ){ |
︙ | ︙ | |||
1527 1528 1529 1530 1531 1532 1533 | ** 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) ** | | | 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 | ** 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 implementation 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 |
︙ | ︙ | |||
2516 2517 2518 2519 2520 2521 2522 | ** } ** while( !eof csrCurrent ){ ** RETURN_ROW ** } ** ** For the most part, the patterns above are adapted to support UNBOUNDED by ** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and | | | 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 | ** } ** while( !eof csrCurrent ){ ** RETURN_ROW ** } ** ** For the most part, the patterns above are adapted to support UNBOUNDED by ** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and ** CURRENT ROW by assuming that it is equivalent to "0 PRECEDING/FOLLOWING". ** This is optimized of course - branches that will never be taken and ** conditions that are always true are omitted from the VM code. The only ** exceptional case is: ** ** ROWS BETWEEN <expr1> FOLLOWING AND UNBOUNDED FOLLOWING ** ** ... loop started by sqlite3WhereBegin() ... |
︙ | ︙ |
Changes to test/alter2.test.
︙ | ︙ | |||
371 372 373 374 375 376 377 | execsql { SELECT a, typeof(a), b, typeof(b), c, typeof(c) FROM t1 LIMIT 1; } } {1 integer -123 integer 5 text} #----------------------------------------------------------------------- # Test that UPDATE trigger tables work with default values, and that when | | | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | execsql { SELECT a, typeof(a), b, typeof(b), c, typeof(c) FROM t1 LIMIT 1; } } {1 integer -123 integer 5 text} #----------------------------------------------------------------------- # Test that UPDATE trigger tables work with default values, and that when # a row is updated the default values are correctly transferred to the # new row. # ifcapable trigger { db function set_val {set ::val} do_test alter2-8.1 { execsql { CREATE TRIGGER trig1 BEFORE UPDATE ON t1 BEGIN |
︙ | ︙ | |||
402 403 404 405 406 407 408 | do_test alter2-8.3 { set ::val } {-123 integer 5 text -123 integer 10 text} } #----------------------------------------------------------------------- # Test that DELETE trigger tables work with default values, and that when | | | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | do_test alter2-8.3 { set ::val } {-123 integer 5 text -123 integer 10 text} } #----------------------------------------------------------------------- # Test that DELETE trigger tables work with default values, and that when # a row is updated the default values are correctly transferred to the # new row. # ifcapable trigger { do_test alter2-9.1 { execsql { CREATE TRIGGER trig2 BEFORE DELETE ON t1 BEGIN SELECT set_val( |
︙ | ︙ |
Changes to test/alter3.test.
︙ | ︙ | |||
99 100 101 102 103 104 105 | CREATE TABLE t3(a, b, UNIQUE(a, b)); ALTER TABLE t3 ADD COLUMN c VARCHAR(10, 20); SELECT sql FROM sqlite_master WHERE tbl_name = 't3' AND type = 'table'; } } {{CREATE TABLE t3(a, b, c VARCHAR(10, 20), UNIQUE(a, b))}} do_test alter3-1.99 { catchsql { | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | CREATE TABLE t3(a, b, UNIQUE(a, b)); ALTER TABLE t3 ADD COLUMN c VARCHAR(10, 20); SELECT sql FROM sqlite_master WHERE tbl_name = 't3' AND type = 'table'; } } {{CREATE TABLE t3(a, b, c VARCHAR(10, 20), UNIQUE(a, b))}} do_test alter3-1.99 { catchsql { # May not exist if foreign-keys are omitted at compile time. DROP TABLE t2; } execsql { DROP TABLE abc; DROP TABLE t1; DROP TABLE t3; } |
︙ | ︙ |
Changes to test/alter4.test.
︙ | ︙ | |||
106 107 108 109 110 111 112 | ALTER TABLE t3 ADD COLUMN c VARCHAR(10, 20); SELECT sql FROM sqlite_temp_master WHERE tbl_name = 't3' AND type = 'table'; } } {{CREATE TABLE t3(a, b, c VARCHAR(10, 20), UNIQUE(a, b))}} do_test alter4-1.99 { catchsql { | | | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | ALTER TABLE t3 ADD COLUMN c VARCHAR(10, 20); SELECT sql FROM sqlite_temp_master WHERE tbl_name = 't3' AND type = 'table'; } } {{CREATE TABLE t3(a, b, c VARCHAR(10, 20), UNIQUE(a, b))}} do_test alter4-1.99 { catchsql { # May not exist if foreign-keys are omitted at compile time. DROP TABLE t2; } execsql { DROP TABLE abc; DROP TABLE t1; DROP TABLE t3; } |
︙ | ︙ |
Changes to test/altertab3.test.
︙ | ︙ | |||
597 598 599 600 601 602 603 | END; } #do_execsql_test 25.2 { # ALTER TABLE t2 RENAME COLUMN a TO aaa; #} finish_test | < | 597 598 599 600 601 602 603 | END; } #do_execsql_test 25.2 { # ALTER TABLE t2 RENAME COLUMN a TO aaa; #} finish_test |
Changes to test/analyze3.test.
︙ | ︙ | |||
34 35 36 37 38 39 40 | # in the same way as constants when planning queries that # use LIKE expressions in the WHERE clause. # # analyze3-3.*: Test that binding to a variable does not invalidate the # query plan when there is no way in which replanning the # query may produce a superior outcome. # | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | # in the same way as constants when planning queries that # use LIKE expressions in the WHERE clause. # # analyze3-3.*: Test that binding to a variable does not invalidate the # query plan when there is no way in which replanning the # query may produce a superior outcome. # # analyze3-4.*: Test that SQL or authorization callback errors occurring # within sqlite3Reprepare() are handled correctly. # # analyze3-5.*: Check that the query plans of applicable statements are # invalidated if the values of SQL parameter are modified # using the clear_bindings() or transfer_bindings() APIs. # # analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed. |
︙ | ︙ |
Changes to test/attach4.test.
︙ | ︙ | |||
131 132 133 134 135 136 137 | } do_execsql_test 2.2 { DROP TRIGGER tr1; } finish_test | < | 131 132 133 134 135 136 137 | } do_execsql_test 2.2 { DROP TRIGGER tr1; } finish_test |
Changes to test/autoindex1.test.
︙ | ︙ | |||
205 206 207 208 209 210 211 | |--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?) `--CORRELATED LIST SUBQUERY xxxxxx `--SCAN TABLE t502 } # The following code checks a performance regression reported on the # mailing list on 2010-10-19. The problem is that the nRowEst field | | | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | |--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?) `--CORRELATED LIST SUBQUERY xxxxxx `--SCAN TABLE t502 } # The following code checks a performance regression reported on the # mailing list on 2010-10-19. The problem is that the nRowEst field # of ephemeral tables was not being initialized correctly and so no # automatic index was being created for the emphemeral table when it was # used as part of a join. # do_execsql_test autoindex1-600 { CREATE TABLE flock_owner( owner_rec_id INTEGER CONSTRAINT flock_owner_key PRIMARY KEY, flock_no VARCHAR(6) NOT NULL REFERENCES flock (flock_no), |
︙ | ︙ |
Changes to test/bestindex4.test.
︙ | ︙ | |||
25 26 27 28 29 30 31 | # Virtual table callback for a virtual table named $tbl. # # The table created is: # # "CREATE TABLE t1 (id, host, class)" # # The virtual table supports == operators on a subset of its columns. The | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # Virtual table callback for a virtual table named $tbl. # # The table created is: # # "CREATE TABLE t1 (id, host, class)" # # The virtual table supports == operators on a subset of its columns. The # exact subset depends on the value of bitmask parameter $param. # # 0x01 - == on "id" supported # 0x02 - == on "host" supported # 0x04 - == on "class" supported # # $param also supports the following bits: # |
︙ | ︙ |
Changes to test/bestindex7.test.
︙ | ︙ | |||
72 73 74 75 76 77 78 | do_execsql_test 1.9 { select * from vt1 WHERE a=1 OR a=0} {0} do_execsql_test 1.10 { select * from vt1 WHERE a IN (2) } {} do_execsql_test 1.10 { select * from vt1 WHERE a IN (0,1,2,3) } {0} do_execsql_test 1.11 { select * from vt1 WHERE a IN (0, NULL) } {0} do_execsql_test 1.12 { select * from vt1 WHERE a IN (NULL) } {} finish_test | < | 72 73 74 75 76 77 78 | do_execsql_test 1.9 { select * from vt1 WHERE a=1 OR a=0} {0} do_execsql_test 1.10 { select * from vt1 WHERE a IN (2) } {} do_execsql_test 1.10 { select * from vt1 WHERE a IN (0,1,2,3) } {0} do_execsql_test 1.11 { select * from vt1 WHERE a IN (0, NULL) } {0} do_execsql_test 1.12 { select * from vt1 WHERE a IN (NULL) } {} finish_test |
Changes to test/bitvec.test.
︙ | ︙ | |||
145 146 147 148 149 150 151 | 1 25 121 125 1 50 121 125 2 25 121 125 0 } } 0 | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | 1 25 121 125 1 50 121 125 2 25 121 125 0 } } 0 # This procedure runs sqlite3BitvecBuiltinTest with arguments "n" and # "program". But it also causes a malloc error to occur after the # "failcnt"-th malloc. The result should be "0" if no malloc failure # occurs or "-1" if there is a malloc failure. # proc bitvec_malloc_test {label failcnt n program} { do_test $label [subst { sqlite3_memdebug_fail $failcnt |
︙ | ︙ |
Changes to test/busy2.test.
︙ | ︙ | |||
125 126 127 128 129 130 131 | code1 { db1.2 close } } finish_test | < | 125 126 127 128 129 130 131 | code1 { db1.2 close } } finish_test |
Changes to test/collate1.test.
︙ | ︙ | |||
19 20 21 22 23 24 25 | # # Tests are roughly organised as follows: # # collate1-1.* - Single-field ORDER BY with an explicit COLLATE clause. # collate1-2.* - Multi-field ORDER BY with an explicit COLLATE clause. # collate1-3.* - ORDER BY using a default collation type. Also that an | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # # Tests are roughly organised as follows: # # collate1-1.* - Single-field ORDER BY with an explicit COLLATE clause. # collate1-2.* - Multi-field ORDER BY with an explicit COLLATE clause. # collate1-3.* - ORDER BY using a default collation type. Also that an # explicit collate type overrides a default collate type. # collate1-4.* - ORDER BY using a data type. # # # Collation type 'HEX'. If an argument can be interpreted as a hexadecimal # number, then it is converted to one before the comparison is performed. # Numbers are less than other strings. If neither argument is a number, |
︙ | ︙ |
Changes to test/collateB.test.
︙ | ︙ | |||
58 59 60 61 62 63 64 | SELECT *,'|' FROM t1, t2, t3 WHERE b=x2 AND a=x1 AND 1=a; } {1 11 1 11 |} do_execsql_test collateB-1.17 { SELECT *,'|' FROM t1, t2, t3 WHERE b=x2 AND a=x1 AND 1=a; } {1 11 1 11 |} #------------------------------------------------------------------------- | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | SELECT *,'|' FROM t1, t2, t3 WHERE b=x2 AND a=x1 AND 1=a; } {1 11 1 11 |} do_execsql_test collateB-1.17 { SELECT *,'|' FROM t1, t2, t3 WHERE b=x2 AND a=x1 AND 1=a; } {1 11 1 11 |} #------------------------------------------------------------------------- # Test an assert() failure that was occurring if an index were created # on a column explicitly declared "COLLATE binary". reset_db do_execsql_test 2.1 { CREATE TABLE t4(a COLLATE binary); CREATE INDEX i4 ON t4(a); INSERT INTO t4 VALUES('one'), ('two'), ('three'); VACUUM; |
︙ | ︙ |
Changes to test/colmeta.test.
︙ | ︙ | |||
93 94 95 96 97 98 99 | set tstbody [concat sqlite3_table_column_metadata $::DB $params] do_test colmeta-$tn.2 { list [catch $tstbody msg] [set msg] } $results } # Calling sqlite3_table_column_metadata with a NULL column name merely | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | set tstbody [concat sqlite3_table_column_metadata $::DB $params] do_test colmeta-$tn.2 { list [catch $tstbody msg] [set msg] } $results } # Calling sqlite3_table_column_metadata with a NULL column name merely # checks for the existence of the table. # do_test colmeta-300 { catch {sqlite3_table_column_metadata $::DB main xyzzy} res } {1} do_test colmeta-301 { catch {sqlite3_table_column_metadata $::DB main abc} res } {0} |
︙ | ︙ |
Changes to test/corruptL.test.
︙ | ︙ | |||
1287 1288 1289 1290 1291 1292 1293 | do_catchsql_test 16.1 { PRAGMA writable_schema = ON; INSERT INTO t1(rowid, w, x, y, z) VALUES(5, 10, 11, 10, NULL); } {1 {database disk image is malformed}} finish_test | < < | 1287 1288 1289 1290 1291 1292 1293 | do_catchsql_test 16.1 { PRAGMA writable_schema = ON; INSERT INTO t1(rowid, w, x, y, z) VALUES(5, 10, 11, 10, NULL); } {1 {database disk image is malformed}} finish_test |
Changes to test/dbfuzz.c.
︙ | ︙ | |||
364 365 366 367 368 369 370 | free(pVFile->a); pVFile->a = 0; return SQLITE_OK; } return SQLITE_IOERR_DELETE; } | | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | free(pVFile->a); pVFile->a = 0; return SQLITE_OK; } return SQLITE_IOERR_DELETE; } /* Check for the existence of a file */ static int inmemAccess( sqlite3_vfs *pVfs, const char *zFilename, int flags, int *pResOut ){ |
︙ | ︙ |
Changes to test/e_createtable.test.
︙ | ︙ | |||
684 685 686 687 688 689 690 | # EVIDENCE-OF: R-16667-09772 A table created using CREATE TABLE AS has # no PRIMARY KEY and no constraints of any kind. The default value of # each column is NULL. The default collation sequence for each column of # the new table is BINARY. # # The following tests create tables based on SELECT statements that read # from tables that have primary keys, constraints and explicit default | | | 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | # EVIDENCE-OF: R-16667-09772 A table created using CREATE TABLE AS has # no PRIMARY KEY and no constraints of any kind. The default value of # each column is NULL. The default collation sequence for each column of # the new table is BINARY. # # The following tests create tables based on SELECT statements that read # from tables that have primary keys, constraints and explicit default # collation sequences. None of this is transferred to the definition of # the new table as stored in the sqlite_master table. # # Tests 2.3.2.* show that the default value of each column is NULL. # do_createtable_tests 2.3.1 -query { SELECT sql FROM sqlite_master ORDER BY rowid DESC LIMIT 1 } { |
︙ | ︙ |
Changes to test/enc.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2002 May 24 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus of # this file is testing the SQLite routines used for converting between the | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 2002 May 24 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus of # this file is testing the SQLite routines used for converting between the # various supported unicode encodings (UTF-8, UTF-16, UTF-16le and # UTF-16be). # # $Id: enc.test,v 1.7 2007/05/23 16:23:09 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl |
︙ | ︙ |
Changes to test/enc2.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2002 May 24 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus of # this file is testing the SQLite routines used for converting between the | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 2002 May 24 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus of # this file is testing the SQLite routines used for converting between the # various supported unicode encodings (UTF-8, UTF-16, UTF-16le and # UTF-16be). # set testdir [file dirname $argv0] source $testdir/tester.tcl # If UTF16 support is disabled, ignore the tests in this file |
︙ | ︙ | |||
59 60 61 62 63 64 65 | # three times. Each time the file 'test.db' contains a database # with the following contents: set dbcontents { CREATE TABLE t1(a PRIMARY KEY, b, c); INSERT INTO t1 VALUES('one', 'I', 1); } # This proc tests that we can open and manipulate the test.db | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | # three times. Each time the file 'test.db' contains a database # with the following contents: set dbcontents { CREATE TABLE t1(a PRIMARY KEY, b, c); INSERT INTO t1 VALUES('one', 'I', 1); } # This proc tests that we can open and manipulate the test.db # database, and that it is possible to retrieve values in # various text encodings. # proc run_test_script {t enc} { # Open the database and pull out a (the) row. do_test $t.1 { sqlite3 db test.db; set DB [sqlite3_connection_pointer db] |
︙ | ︙ |
Changes to test/enc4.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2010 Sept 29 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus of # this file is testing the SQLite routines used for converting between the | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 2010 Sept 29 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The focus of # this file is testing the SQLite routines used for converting between the # various supported unicode encodings (UTF-8, UTF-16, UTF-16le and # UTF-16be). # # $Id: enc4.test,v 1.0 2010/09/29 08:29:32 shaneh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl |
︙ | ︙ |
Changes to test/filter2.tcl.
︙ | ︙ | |||
124 125 126 127 128 129 130 | 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 | < < | 124 125 126 127 128 129 130 | 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 |
Changes to test/fts3_common.tcl.
︙ | ︙ | |||
413 414 415 416 417 418 419 | } } } } ########################################################################## | < | 413 414 415 416 417 418 419 | } } } } ########################################################################## |
Changes to test/fts3corrupt6.test.
︙ | ︙ | |||
52 53 54 55 56 57 58 | do_execsql_test 1.3 { SELECT 42+matchinfo(t1,'yxyyxy') FROM t1 WHERE t1 MATCH x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d'; } {42} set sqlite_fts3_enable_parentheses $saved_sqlite_fts3_enable_parentheses finish_test | < < | 52 53 54 55 56 57 58 | do_execsql_test 1.3 { SELECT 42+matchinfo(t1,'yxyyxy') FROM t1 WHERE t1 MATCH x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d'; } {42} set sqlite_fts3_enable_parentheses $saved_sqlite_fts3_enable_parentheses finish_test |
Changes to test/fts3cov.test.
︙ | ︙ | |||
21 22 23 24 25 26 27 | set DO_MALLOC_TEST 0 set testprefix fts3cov #-------------------------------------------------------------------------- # When it first needs to read a block from the %_segments table, the FTS3 # module compiles an SQL statement for that purpose. The statement is # stored and reused each subsequent time a block is read. This test case | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | set DO_MALLOC_TEST 0 set testprefix fts3cov #-------------------------------------------------------------------------- # When it first needs to read a block from the %_segments table, the FTS3 # module compiles an SQL statement for that purpose. The statement is # stored and reused each subsequent time a block is read. This test case # tests the effects of an OOM error occurring while compiling the statement. # # Similarly, when FTS3 first needs to scan through a set of segment leaves # to find a set of documents that matches a term, it allocates a string # containing the text of the required SQL, and compiles one or more # statements to traverse the leaves. This test case tests that OOM errors # that occur while allocating this string and statement are handled correctly # also. |
︙ | ︙ | |||
273 274 275 276 277 278 279 | } {1 D E F 5 A B C} #------------------------------------------------------------------------- # If a set of documents are modified within a transaction, the # pending-terms table must be flushed each time a document with a docid # less than or equal to the previous docid is modified. # | | | 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | } {1 D E F 5 A B C} #------------------------------------------------------------------------- # If a set of documents are modified within a transaction, the # pending-terms table must be flushed each time a document with a docid # less than or equal to the previous docid is modified. # # This test checks the effects of an OOM error occurring when the # pending-terms table is flushed for this reason as part of a DELETE # statement. # do_malloc_test fts3cov-8 -sqlprep { BEGIN; CREATE VIRTUAL TABLE t8 USING fts3; INSERT INTO t8 VALUES('the output of each batch run'); |
︙ | ︙ |
Changes to test/fts3expr2.test.
︙ | ︙ | |||
42 43 44 45 46 47 48 | # # In step (2), 4 different fts3 expressions are created from each # expression tree by varying the following boolean properties: # # * Whether or not superflous parenthesis are included. i.e. if # "a OR b AND (c OR d)" or "a OR (b AND (c OR d))" is generated. # | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | # # In step (2), 4 different fts3 expressions are created from each # expression tree by varying the following boolean properties: # # * Whether or not superflous parenthesis are included. i.e. if # "a OR b AND (c OR d)" or "a OR (b AND (c OR d))" is generated. # # * Whether or not explicit AND operators are used. i.e. if # "a OR b AND c" or "a OR b c" is generated. # set sqlite_fts3_enable_parentheses 1 proc strip_phrase_data {L} { if {[lindex $L 0] eq "PHRASE"} { |
︙ | ︙ |
Changes to test/fts3snippet2.test.
︙ | ︙ | |||
53 54 55 56 57 58 59 | do_execsql_test 2.2 { SELECT snippet(t0) FROM t0 WHERE t0 MATCH '(def AND (one NEAR abc)) OR one' } {<b>one</b>} set sqlite_fts3_enable_parentheses 0 finish_test | < | 53 54 55 56 57 58 59 | do_execsql_test 2.2 { SELECT snippet(t0) FROM t0 WHERE t0 MATCH '(def AND (one NEAR abc)) OR one' } {<b>one</b>} set sqlite_fts3_enable_parentheses 0 finish_test |
Changes to test/fts4upfrom.test.
︙ | ︙ | |||
133 134 135 136 137 138 139 | 12 b apple blueberry 13 c banana clementine 14 d cherry dewberry } } finish_test | < | 133 134 135 136 137 138 139 | 12 b apple blueberry 13 c banana clementine 14 d cherry dewberry } } finish_test |
Changes to test/fuzzcheck.c.
︙ | ︙ | |||
1157 1158 1159 1160 1161 1162 1163 | free(pVFile->a); pVFile->a = 0; return SQLITE_OK; } return SQLITE_IOERR_DELETE; } | | | 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 | free(pVFile->a); pVFile->a = 0; return SQLITE_OK; } return SQLITE_IOERR_DELETE; } /* Check for the existence of a file */ static int inmemAccess( sqlite3_vfs *pVfs, const char *zFilename, int flags, int *pResOut ){ |
︙ | ︙ | |||
1455 1456 1457 1458 1459 1460 1461 | int timeoutTest = 0; /* undocumented --timeout-test flag */ int runFlags = 0; /* Flags sent to runSql() */ char *zMsg = 0; /* Add this message */ int nSrcDb = 0; /* Number of source databases */ char **azSrcDb = 0; /* Array of source database names */ int iSrcDb; /* Loop over all source databases */ int nTest = 0; /* Total number of tests performed */ | | | 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 | int timeoutTest = 0; /* undocumented --timeout-test flag */ int runFlags = 0; /* Flags sent to runSql() */ char *zMsg = 0; /* Add this message */ int nSrcDb = 0; /* Number of source databases */ char **azSrcDb = 0; /* Array of source database names */ int iSrcDb; /* Loop over all source databases */ int nTest = 0; /* Total number of tests performed */ char *zDbName = ""; /* Abbreviated name of a source database */ const char *zFailCode = 0; /* Value of the TEST_FAILURE env variable */ int cellSzCkFlag = 0; /* --cell-size-check */ int sqlFuzz = 0; /* True for SQL fuzz. False for DB fuzz */ int iTimeout = 120; /* Default 120-second timeout */ int nMem = 0; /* Memory limit override */ int nMemThisDb = 0; /* Memory limit set by the CONFIG table */ char *zExpDb = 0; /* Write Databases to files in this directory */ |
︙ | ︙ |
Changes to test/hook.test.
︙ | ︙ | |||
79 80 81 82 83 84 85 | do_test hook-3.7 { set ::commit_cnt } {1 2 2 3 3 4 4 5 5 6 6 7} do_test hook-3.8 { execsql {SELECT * FROM t2} } {1 2 2 3 3 4 4 5 5 6} | | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | do_test hook-3.7 { set ::commit_cnt } {1 2 2 3 3 4 4 5 5 6 6 7} do_test hook-3.8 { execsql {SELECT * FROM t2} } {1 2 2 3 3 4 4 5 5 6} # Test turning off the commit hook # do_test hook-3.9 { db commit_hook {} set ::commit_cnt {} execsql { INSERT INTO t2 VALUES(7,8); } |
︙ | ︙ |
Changes to test/in.test.
︙ | ︙ | |||
637 638 639 640 641 642 643 | do_test in-13.X { db nullvalue "" } {} # At one point the following was causing valgrind to report a "jump | | | 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 | do_test in-13.X { db nullvalue "" } {} # At one point the following was causing valgrind to report a "jump # depends on uninitialized location" problem. # do_execsql_test in-14.0 { CREATE TABLE c1(a); INSERT INTO c1 VALUES(1), (2), (4), (3); } do_execsql_test in-14.1 { SELECT * FROM c1 WHERE a IN (SELECT a FROM c1) ORDER BY 1 |
︙ | ︙ |
Changes to test/indexfault.test.
︙ | ︙ | |||
167 168 169 170 171 172 173 | # second temporary file. # 3.4: As 7.3, but with a low (50KB) soft-heap-limit. # # 3.5: After a certain amount of data has been read from the main database # file (and written into the temporary b-tree), sqlite3_release_memory() # is called to free as much memory as possible. This causes the temp # b-tree to be flushed to disk. So that before its contents can be | | | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | # second temporary file. # 3.4: As 7.3, but with a low (50KB) soft-heap-limit. # # 3.5: After a certain amount of data has been read from the main database # file (and written into the temporary b-tree), sqlite3_release_memory() # is called to free as much memory as possible. This causes the temp # b-tree to be flushed to disk. So that before its contents can be # transferred to a PMA they must be read back from disk - creating extra # opportunities for IO errors. # install_custom_faultsim # Set up a table to build indexes on. Save the setup using the # [faultsim_save_and_close] mechanism. # |
︙ | ︙ | |||
265 266 267 268 269 270 271 | uninstall_custom_faultsim #------------------------------------------------------------------------- # Test 4: After a certain amount of data has been read from the main database # file (and written into the temporary b-tree), sqlite3_release_memory() is # called to free as much memory as possible. This causes the temp b-tree to be | | | 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | uninstall_custom_faultsim #------------------------------------------------------------------------- # Test 4: After a certain amount of data has been read from the main database # file (and written into the temporary b-tree), sqlite3_release_memory() is # called to free as much memory as possible. This causes the temp b-tree to be # flushed to disk. So that before its contents can be transferred to a PMA they # must be read back from disk - creating extra opportunities for IO errors. # install_custom_faultsim catch { db close } forcedelete test.db sqlite3 db test.db |
︙ | ︙ |
Changes to test/insert.test.
︙ | ︙ | |||
325 326 327 328 329 330 331 | DROP TABLE t1; } } {} } # Test that the special optimization for queries of the form # "SELECT max(x) FROM tbl" where there is an index on tbl(x) works with | | | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | DROP TABLE t1; } } {} } # Test that the special optimization for queries of the form # "SELECT max(x) FROM tbl" where there is an index on tbl(x) works with # INSERT statements. do_test insert-7.1 { execsql { CREATE TABLE t1(a); INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(2); CREATE INDEX i1 ON t1(a); } |
︙ | ︙ |
Changes to test/insert4.test.
︙ | ︙ | |||
129 130 131 132 133 134 135 | # not, as appropriate. # # xfer_check TESTID XFER-USED INIT-DATA DEST-SCHEMA SRC-SCHEMA # # The TESTID argument is the symbolic name for this test. The XFER-USED # argument is true if the transfer optimization should be employed and # false if not. INIT-DATA is a single row of data that is to be | | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | # not, as appropriate. # # xfer_check TESTID XFER-USED INIT-DATA DEST-SCHEMA SRC-SCHEMA # # The TESTID argument is the symbolic name for this test. The XFER-USED # argument is true if the transfer optimization should be employed and # false if not. INIT-DATA is a single row of data that is to be # transferred. DEST-SCHEMA and SRC-SCHEMA are table declarations for # the destination and source tables. # proc xfer_check {testid xferused initdata destschema srcschema} { execsql "CREATE TABLE dest($destschema)" execsql "CREATE TABLE src($srcschema)" execsql "INSERT INTO src VALUES([join $initdata ,])" set ::sqlite3_xferopt_count 0 |
︙ | ︙ |
Changes to test/join.test.
︙ | ︙ | |||
1022 1023 1024 1025 1026 1027 1028 | } {} do_execsql_test join-24.2 { SELECT * FROM t2 LEFT JOIN t1 ON a=0 WHERE (x='x' OR x IS NULL); } {1 {} {}} finish_test | < | 1022 1023 1024 1025 1026 1027 1028 | } {} do_execsql_test join-24.2 { SELECT * FROM t2 LEFT JOIN t1 ON a=0 WHERE (x='x' OR x IS NULL); } {1 {} {}} finish_test |
Changes to test/journal1.test.
︙ | ︙ | |||
16 17 18 19 20 21 22 | # $Id: journal1.test,v 1.2 2005/03/20 22:54:56 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # These tests will not work on windows because windows uses | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # $Id: journal1.test,v 1.2 2005/03/20 22:54:56 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # These tests will not work on windows because windows uses # mandatory file locking which breaks the copy_file command. # # Or with atomic_batch_write systems, as journal files are # not created. # if {$tcl_platform(platform)=="windows" || [atomic_batch_write test.db] } { |
︙ | ︙ |
Changes to test/json101.test.
︙ | ︙ | |||
719 720 721 722 723 724 725 | do_execsql_test json-11.3 { /* Too deep by one { */ SELECT json_valid(replace(printf('%.2001c0%.2001c','[','}'),'[','{"a":')); /* } */ } {0} # 2017-10-27. Demonstrate the ability to access an element from | | | 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 | do_execsql_test json-11.3 { /* Too deep by one { */ SELECT json_valid(replace(printf('%.2001c0%.2001c','[','}'),'[','{"a":')); /* } */ } {0} # 2017-10-27. Demonstrate the ability to access an element from # a json structure even though the element name contains a "." # character, by quoting the element name in the path. # do_execsql_test json-12.100 { CREATE TABLE t12(x); INSERT INTO t12(x) VALUES( '{"settings": {"layer2": |
︙ | ︙ |
Changes to test/kvtest.c.
︙ | ︙ | |||
20 21 22 23 24 25 26 | ** HOW TO COMPILE: ** ** (1) Gather this source file and a recent SQLite3 amalgamation with its ** header into the working directory. You should have: ** ** kvtest.c >--- this file ** sqlite3.c \___ SQLite | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ** HOW TO COMPILE: ** ** (1) Gather this source file and a recent SQLite3 amalgamation with its ** header into the working directory. You should have: ** ** kvtest.c >--- this file ** sqlite3.c \___ SQLite ** sqlite3.h / amalagmation & header ** ** (2) Run you compiler against the two C source code files. ** ** (a) On linux or mac: ** ** OPTS="-DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION" ** gcc -Os -I. $OPTS kvtest.c sqlite3.c -o kvtest |
︙ | ︙ |
Changes to test/lock.test.
︙ | ︙ | |||
173 174 175 176 177 178 179 | # do_test lock-2.2 { catchsql {SELECT * FROM t2} db2 } {0 {9 8}} # If the other thread (the one that does not hold the transaction with # a RESERVED lock) tries to get a RESERVED lock, we do get a busy callback | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | # do_test lock-2.2 { catchsql {SELECT * FROM t2} db2 } {0 {9 8}} # If the other thread (the one that does not hold the transaction with # a RESERVED lock) tries to get a RESERVED lock, we do get a busy callback # as long as we were not originally holding a READ lock. # do_test lock-2.3.1 { proc callback {count} { set ::callback_value $count break } set ::callback_value {} |
︙ | ︙ |
Changes to test/lock2.test.
︙ | ︙ | |||
24 25 26 27 28 29 30 | # lock2-1.1: Connect a second process to the database. # lock2-1.2: Establish a RESERVED lock with this process. # lock2-1.3: Get a SHARED lock with the second process. # lock2-1.4: Try for a RESERVED lock with process 2. This fails. # lock2-1.5: Try to upgrade the first process to EXCLUSIVE, this fails so # it gets PENDING. # lock2-1.6: Release the SHARED lock held by the second process. | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | # lock2-1.1: Connect a second process to the database. # lock2-1.2: Establish a RESERVED lock with this process. # lock2-1.3: Get a SHARED lock with the second process. # lock2-1.4: Try for a RESERVED lock with process 2. This fails. # lock2-1.5: Try to upgrade the first process to EXCLUSIVE, this fails so # it gets PENDING. # lock2-1.6: Release the SHARED lock held by the second process. # lock2-1.7: Attempt to reacquire a SHARED lock with the second process. # this fails due to the PENDING lock. # lock2-1.8: Ensure the first process can now upgrade to EXCLUSIVE. # do_test lock2-1.1 { set ::tf1 [launch_testfixture] testfixture $::tf1 { sqlite3 db test.db -key xyzzy |
︙ | ︙ |
Changes to test/lock_common.tcl.
︙ | ︙ | |||
199 200 201 202 203 204 205 | append script "\n" } } }] close $fd set main_loop_written 1 } | < | 199 200 201 202 203 204 205 | append script "\n" } } }] close $fd set main_loop_written 1 } |
Changes to test/malloc_common.tcl.
︙ | ︙ | |||
367 368 369 370 371 372 373 | # injected into the system this trial. # eval $O(-injectstart) $iFail set rc [catch $O(-body) res] set nfail [eval $O(-injectstop)] # Run the -test script. If it throws no error, consider this trial | | | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | # injected into the system this trial. # eval $O(-injectstart) $iFail set rc [catch $O(-body) res] set nfail [eval $O(-injectstop)] # Run the -test script. If it throws no error, consider this trial # successful. If it does throw an error, cause a [do_test] test to # fail (and print out the unexpected exception thrown by the -test # script at the same time). # set rc [catch [list faultsim_test_proc $rc $res $nfail] res] if {$rc == 0} {set res ok} do_test $testname.$iFail [list list $rc $res] {0 ok} |
︙ | ︙ |
Changes to test/malloctraceviewer.tcl.
︙ | ︙ | |||
246 247 248 249 250 251 252 | } } open_database bind $O(tree) <<TreeviewSelect>> [list populate_text_widget mddb] populate_tree_widget mddb [mddb one {SELECT zTest FROM malloc LIMIT 1}] | < | 246 247 248 249 250 251 252 | } } open_database bind $O(tree) <<TreeviewSelect>> [list populate_text_widget mddb] populate_tree_widget mddb [mddb one {SELECT zTest FROM malloc LIMIT 1}] |
Changes to test/misc1.test.
︙ | ︙ | |||
341 342 343 344 345 346 347 | set rc [catch {db2 eval {SELECT count(*) FROM t1}} msg] db2 close lappend rc $msg } {0 3} # Make sure string comparisons really do compare strings in format4+. # Similar tests in the format3.test file show that for format3 and earlier | | | 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | set rc [catch {db2 eval {SELECT count(*) FROM t1}} msg] db2 close lappend rc $msg } {0 3} # Make sure string comparisons really do compare strings in format4+. # Similar tests in the format3.test file show that for format3 and earlier # all comparisons where numeric if either operand looked like a number. # do_test misc1-12.1 { execsql {SELECT '0'=='0.0'} } {0} do_test misc1-12.2 { execsql {SELECT '0'==0.0} } {0} |
︙ | ︙ |
Changes to test/misc4.test.
︙ | ︙ | |||
216 217 218 219 220 221 222 | do_catchsql_test misc4-7.1 { CREATE TABLE t7(x); PRAGMA writable_schema=ON; UPDATE sqlite_master SET sql='CREATE TABLE [M%s%s%s%s%s%s%s%s%s%s%s%s%s'; VACUUM; } {1 {unrecognized token: "[M%s%s%s%s%s%s%s%s%s%s%s%s%s"}} | | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | do_catchsql_test misc4-7.1 { CREATE TABLE t7(x); PRAGMA writable_schema=ON; UPDATE sqlite_master SET sql='CREATE TABLE [M%s%s%s%s%s%s%s%s%s%s%s%s%s'; VACUUM; } {1 {unrecognized token: "[M%s%s%s%s%s%s%s%s%s%s%s%s%s"}} # 2015-05-18. Use of ephemeral Mem content after the cursor that holds # the canonical content has moved on. # do_execsql_test misc4-7.2 { CREATE TABLE t0(a,b); INSERT INTO t0 VALUES(1,0),(2,0); UPDATE t0 SET b=9 WHERE a AND (SELECT a FROM t0 WHERE a); SELECT * FROM t0 ORDER BY +a; |
︙ | ︙ |
Changes to test/pg_common.tcl.
︙ | ︙ | |||
168 169 170 171 172 173 174 | puts $::fd finish_test close $::fd } proc ifcapable {arg} { puts $::fd "ifcapable $arg { finish_test ; return }" } | < | 168 169 170 171 172 173 174 | puts $::fd finish_test close $::fd } proc ifcapable {arg} { puts $::fd "ifcapable $arg { finish_test ; return }" } |
Changes to test/releasetest.tcl.
︙ | ︙ | |||
736 737 738 739 740 741 742 | set cflags [join $cflags " "] set opts [join $opts " "] lappend alltests [list \ $title $dir $configOpts $testtarget $makeOpts $cflags $opts] } | | | 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 | set cflags [join $cflags " "] set opts [join $opts " "] lappend alltests [list \ $title $dir $configOpts $testtarget $makeOpts $cflags $opts] } # The following procedure returns the "configure" command to be executed for # the current platform, which may be Windows (via MinGW, etc). # proc configureCommand {opts} { if {$::MSVC} return [list]; # This is not needed for MSVC. set result [list trace_cmd exec] if {$::tcl_platform(platform)=="windows"} { lappend result sh |
︙ | ︙ |
Changes to test/releasetest_data.tcl.
︙ | ︙ | |||
601 602 603 604 605 606 607 | } elseif {[string match ${cmd}* platforms] && $n==0} { main_platforms } elseif {[string match ${cmd}* tests]} { main_tests {*}[lrange $argv 1 end] } else { usage } | < < | 601 602 603 604 605 606 607 | } 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/rollback2.test.
︙ | ︙ | |||
38 39 40 41 42 43 44 | # # where SWITCHES are: # # -setup SQL script to open transaction and begin writing. # -select SELECT to execute after -setup script # -result Expected result of -select statement # -rollback Use this SQL command ("ROLLBACK" or "ROLLBACK TO ...") to | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # # where SWITCHES are: # # -setup SQL script to open transaction and begin writing. # -select SELECT to execute after -setup script # -result Expected result of -select statement # -rollback Use this SQL command ("ROLLBACK" or "ROLLBACK TO ...") to # rollback the transaction in the middle of the -select statement # execution. # proc do_rollback_test {tn args} { set A(-setup) "" set A(-select) "" set A(-result) "" set A(-rollback) ROLLBACK |
︙ | ︙ |
Changes to test/rowid.test.
︙ | ︙ | |||
685 686 687 688 689 690 691 | execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc' ORDER BY 1 DESC} } {8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1} # Test the automatic generation of rowids when the table already contains # a rowid with the maximum value. # # Once the maximum rowid is taken, rowids are normally chosen at | | | 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 | execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc' ORDER BY 1 DESC} } {8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1} # Test the automatic generation of rowids when the table already contains # a rowid with the maximum value. # # Once the maximum rowid is taken, rowids are normally chosen at # random. By by resetting the random number generator, we can cause # the rowid guessing loop to collide with prior rowids, and test the # loop out to its limit of 100 iterations. After 100 collisions, the # rowid guesser gives up and reports SQLITE_FULL. # do_test rowid-12.1 { execsql { CREATE TABLE t7(x INTEGER PRIMARY KEY, y); |
︙ | ︙ |
Changes to test/savepoint.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/malloc_common.tcl #---------------------------------------------------------------------- # The following tests - savepoint-1.* - test that the SAVEPOINT, RELEASE | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/malloc_common.tcl #---------------------------------------------------------------------- # The following tests - savepoint-1.* - test that the SAVEPOINT, RELEASE # and ROLLBACK TO commands are correctly parsed, and that the auto-commit # flag is correctly set and unset as a result. # do_test savepoint-1.1 { wal_set_journal_mode execsql { SAVEPOINT sp1; RELEASE sp1; |
︙ | ︙ |
Changes to test/sessionfuzz.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | ** This file implements a program used for fuzz-testing the session ** module. ** ** Usage: ** ** sessionfuzz setup -- Generate starter test cases ** sessionfuzz run FILE ... -- Run a test fuzz on FILE | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | ** This file implements a program used for fuzz-testing the session ** module. ** ** Usage: ** ** sessionfuzz setup -- Generate starter test cases ** sessionfuzz run FILE ... -- Run a test fuzz on FILE ** sessionfuzz run SQLAR ... -- Run all test cases in the SQL Archive ** ** Compiling: ** ** (1) Have a version of SQLite that supports SQLITE_ENABLE_MEMDB ** in the local directory. ** (2) Run: ** |
︙ | ︙ |
Changes to test/shared.test.
︙ | ︙ | |||
310 311 312 313 314 315 316 | do_test shared-$av.4.1.3 { execsql {ATTACH 'test.db' AS test} db2 set sqlite_open_file_count expr $sqlite_open_file_count-($extrafds_postlock*2) } {2} # Sanity check: Create a table in ./test.db via handle db, and test that handle | | | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | do_test shared-$av.4.1.3 { execsql {ATTACH 'test.db' AS test} db2 set sqlite_open_file_count expr $sqlite_open_file_count-($extrafds_postlock*2) } {2} # Sanity check: Create a table in ./test.db via handle db, and test that handle # db2 can "see" the new table immediately. A handle using a separate pager # cache would have to reload the database schema before this were possible. # do_test shared-$av.4.2.1 { execsql { CREATE TABLE abc(a, b, c); CREATE TABLE def(d, e, f); INSERT INTO abc VALUES('i', 'ii', 'iii'); |
︙ | ︙ |
Changes to test/shell3.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | # The focus of this file is testing the CLI shell tool. # # $Id: shell2.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $ # # Test plan: # | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # The focus of this file is testing the CLI shell tool. # # $Id: shell2.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $ # # Test plan: # # shell3-1.*: Basic tests for running SQL statements from command line. # shell3-2.*: Basic tests for running SQL file from command line. # set testdir [file dirname $argv0] source $testdir/tester.tcl set CLI [test_find_cli] db close forcedelete test.db test.db-journal test.db-wal |
︙ | ︙ | |||
35 36 37 38 39 40 41 | # if {$::tcl_platform(platform)=="windows"} { finish_test return } #---------------------------------------------------------------------------- | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | # if {$::tcl_platform(platform)=="windows"} { finish_test return } #---------------------------------------------------------------------------- # shell3-1.*: Basic tests for running SQL statements from command line. # # Run SQL statement from command line do_test shell3-1.1 { forcedelete foo.db set rc [ catchcmd "foo.db \"CREATE TABLE t1(a);\"" ] set fexist [file exist foo.db] |
︙ | ︙ |
Changes to test/speed1.test.
︙ | ︙ | |||
27 28 29 30 31 32 33 | set sqlout [open speed1.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | set sqlout [open speed1.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql # The number_name procedure below converts its argument (an integer) # into a string which is the English-language name for that number. # # Example: # # puts [number_name 123] -> "one hundred twenty three" # set ones {zero one two three four five six seven eight nine |
︙ | ︙ |
Changes to test/speed1p.explain.
︙ | ︙ | |||
25 26 27 28 29 30 31 | set sqlout [open speed1.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | set sqlout [open speed1.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql # The number_name procedure below converts its argument (an integer) # into a string which is the English-language name for that number. # # Example: # # puts [number_name 123] -> "one hundred twenty three" # set ones {zero one two three four five six seven eight nine |
︙ | ︙ |
Changes to test/speed1p.test.
︙ | ︙ | |||
25 26 27 28 29 30 31 | speed_trial_init speed1 sqlite3_memdebug_vfs_oom_test 0 # Set a uniform random seed expr srand(0) | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | speed_trial_init speed1 sqlite3_memdebug_vfs_oom_test 0 # Set a uniform random seed expr srand(0) # The number_name procedure below converts its argument (an integer) # into a string which is the English-language name for that number. # # Example: # # puts [number_name 123] -> "one hundred twenty three" # set ones {zero one two three four five six seven eight nine |
︙ | ︙ |
Changes to test/speed2.test.
︙ | ︙ | |||
23 24 25 26 27 28 29 | set sqlout [open speed2.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | set sqlout [open speed2.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql # The number_name procedure below converts its argument (an integer) # into a string which is the English-language name for that number. # # Example: # # puts [number_name 123] -> "one hundred twenty three" # set ones {zero one two three four five six seven eight nine |
︙ | ︙ |
Changes to test/speed3.test.
︙ | ︙ | |||
43 44 45 46 47 48 49 | speed_trial_init speed1 # Set a uniform random seed expr srand(0) set ::NROW 1000 | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | speed_trial_init speed1 # Set a uniform random seed expr srand(0) set ::NROW 1000 # The number_name procedure below converts its argument (an integer) # into a string which is the English-language name for that number. # # Example: # # puts [number_name 123] -> "one hundred twenty three" # set ones {zero one two three four five six seven eight nine |
︙ | ︙ |
Changes to test/speed4.test.
︙ | ︙ | |||
29 30 31 32 33 34 35 | set sqlout [open speed1.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | set sqlout [open speed1.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql # The number_name procedure below converts its argument (an integer) # into a string which is the English-language name for that number. # # Example: # # puts [number_name 123] -> "one hundred twenty three" # set ones {zero one two three four five six seven eight nine |
︙ | ︙ |
Changes to test/speed4p.explain.
︙ | ︙ | |||
29 30 31 32 33 34 35 | set sqlout [open speed1.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | set sqlout [open speed1.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql # The number_name procedure below converts its argument (an integer) # into a string which is the English-language name for that number. # # Example: # # puts [number_name 123] -> "one hundred twenty three" # set ones {zero one two three four five six seven eight nine |
︙ | ︙ |
Changes to test/speed4p.test.
︙ | ︙ | |||
29 30 31 32 33 34 35 | set sqlout [open speed1.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | set sqlout [open speed1.txt w] proc tracesql {sql} { puts $::sqlout $sql\; } #db trace tracesql # The number_name procedure below converts its argument (an integer) # into a string which is the English-language name for that number. # # Example: # # puts [number_name 123] -> "one hundred twenty three" # set ones {zero one two three four five six seven eight nine |
︙ | ︙ |
Changes to test/speedtest1.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** A program for performance testing. ** ** The available command-line options are described below: */ static const char zHelp[] = "Usage: %s [--options] DATABASE\n" "Options:\n" " --autovacuum Enable AUTOVACUUM mode\n" " --cachesize N Set the cache size to N\n" " --exclusive Enable locking_mode=EXCLUSIVE\n" " --explain Like --sqlonly but with added EXPLAIN keywords\n" " --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n" | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** A program for performance testing. ** ** The available command-line options are described below: */ static const char zHelp[] = "Usage: %s [--options] DATABASE\n" "Options:\n" " --autovacuum Enable AUTOVACUUM mode\n" " --cachesize N Set the cache size to N\n" " --exclusive Enable locking_mode=EXCLUSIVE\n" " --explain Like --sqlonly but with added EXPLAIN keywords\n" " --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n" " --incrvacuum Enable incremental vacuum mode\n" " --journal M Set the journal_mode to M\n" " --key KEY Set the encryption key to KEY\n" " --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n" " --memdb Use an in-memory database\n" " --mmap SZ MMAP the first SZ bytes of the database file\n" " --multithread Set multithreaded mode\n" " --nomemstat Disable memory statistics\n" |
︙ | ︙ | |||
275 276 277 278 279 280 281 | unsigned int speedtest1_random(void){ g.x = (g.x>>1) ^ ((1+~(g.x&1)) & 0xd0000001); g.y = g.y*1103515245 + 12345; return g.x ^ g.y; } /* Map the value in within the range of 1...limit into another | | | | 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 | unsigned int speedtest1_random(void){ g.x = (g.x>>1) ^ ((1+~(g.x&1)) & 0xd0000001); g.y = g.y*1103515245 + 12345; return g.x ^ g.y; } /* Map the value in within the range of 1...limit into another ** number in a way that is chaotic and invertable. */ unsigned swizzle(unsigned in, unsigned limit){ unsigned out = 0; while( limit ){ out = (out<<1) | (in&1); in >>= 1; limit >>= 1; } return out; } /* Round up a number so that it is a power of two minus one */ unsigned roundup_allones(unsigned limit){ unsigned m = 1; while( m<limit ) m = (m<<1)+1; return m; } /* The speedtest1_numbername procedure below converts its argument (an integer) ** into a string which is the English-language name for that number. ** The returned string should be freed with sqlite3_free(). ** ** Example: ** ** speedtest1_numbername(123) -> "one hundred twenty three" */ |
︙ | ︙ |
Changes to test/subquery.test.
︙ | ︙ | |||
220 221 222 223 224 225 226 | INSERT INTO t4 VALUES('10.0'); } } {} do_test subquery-2.5.2 { # In the expr "x IN (SELECT a FROM t3)" the RHS of the IN operator # has text affinity and the LHS has integer affinity. The rule is # that we try to convert both sides to an integer before doing the | | | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | INSERT INTO t4 VALUES('10.0'); } } {} do_test subquery-2.5.2 { # In the expr "x IN (SELECT a FROM t3)" the RHS of the IN operator # has text affinity and the LHS has integer affinity. The rule is # that we try to convert both sides to an integer before doing the # comparison. Hence, the integer value 10 in t3 will compare equal # to the string value '10.0' in t4 because the t4 value will be # converted into an integer. execsql { SELECT * FROM t4 WHERE x IN (SELECT a FROM t3); } } {10.0} do_test subquery-2.5.3.1 { |
︙ | ︙ |
Changes to test/tableapi.test.
︙ | ︙ | |||
226 227 228 229 230 231 232 | ifcapable schema_pragmas { do_test tableapi-6.1 { sqlite3_get_table_printf $::dbx {PRAGMA user_version} {} } {0 1 1 user_version 0} } # do_malloc_test closes and deletes the usual db connections and files on | | | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | ifcapable schema_pragmas { do_test tableapi-6.1 { sqlite3_get_table_printf $::dbx {PRAGMA user_version} {} } {0 1 1 user_version 0} } # do_malloc_test closes and deletes the usual db connections and files on # each iteration. $::dbx is a separate connection, and on Windows, will # cause the file deletion of test.db to fail, so we move the close of $::dbx # up to here before the do_malloc_test. do_test tableapi-99.0 { sqlite3_close $::dbx } {SQLITE_OK} do_malloc_test tableapi-7 -sqlprep { |
︙ | ︙ |
Changes to test/tester.tcl.
︙ | ︙ | |||
31 32 33 34 35 36 37 | # # Test the capability of the SQLite version built into the interpreter to # determine if a specific test can be run: # # capable EXPR # ifcapable EXPR # | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | # # Test the capability of the SQLite version built into the interpreter to # determine if a specific test can be run: # # capable EXPR # ifcapable EXPR # # Calculate checksums based on database contents: # # dbcksum DB DBNAME # allcksum ?DB? # cksum ?DB? # # Commands to execute/explain SQL statements: # |
︙ | ︙ | |||
85 86 87 88 89 90 91 | # Command to test whether or not --verbose=1 was specified on the command # line (returns 0 for not-verbose, 1 for verbose and 2 for "verbose in the # output file only"). # # verbose # | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | # Command to test whether or not --verbose=1 was specified on the command # line (returns 0 for not-verbose, 1 for verbose and 2 for "verbose in the # output file only"). # # verbose # # Set the precision of FP arithmetic used by the interpreter. And # configure SQLite to take database file locks on the page that begins # 64KB into the database file instead of the one 1GB in. This means # the code that handles that special case can be tested without creating # very large database files. # set tcl_precision 15 sqlite3_test_control_pending_byte 0x0010000 |
︙ | ︙ | |||
1631 1632 1633 1634 1635 1636 1637 | set c [catch {uplevel 1 $code} r] } else { set c [catch {uplevel 1 $elsecode} r] } return -code $c $r } | | | 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 | set c [catch {uplevel 1 $code} r] } else { set c [catch {uplevel 1 $elsecode} r] } return -code $c $r } # This proc execs a separate process that crashes midway through executing # the SQL script $sql on database test.db. # # The crash occurs during a sync() of file $crashfile. When the crash # occurs a random subset of all unsynced writes made by the process are # written into the files on disk. Argument $crashdelay indicates the # number of file syncs to wait before crashing. # |
︙ | ︙ | |||
2328 2329 2330 2331 2332 2333 2334 | # Add some info to the output. # output2 "Time: $tail $ms ms" show_memstats } # Open a new connection on database test.db and execute the SQL script | | | 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 | # Add some info to the output. # output2 "Time: $tail $ms ms" show_memstats } # Open a new connection on database test.db and execute the SQL script # supplied as an argument. Before returning, close the new connection and # restore the 4 byte fields starting at header offsets 28, 92 and 96 # to the values they held before the SQL was executed. This simulates # a write by a pre-3.7.0 client. # proc sql36231 {sql} { set B [hexio_read test.db 92 8] set A [hexio_read test.db 28 4] |
︙ | ︙ |
Changes to test/thread_common.tcl.
︙ | ︙ | |||
103 104 105 106 107 108 109 | return 0 } set ::run_thread_tests_called 1 return 1; } return 0 | < | 103 104 105 106 107 108 109 | return 0 } set ::run_thread_tests_called 1 return 1; } return 0 |
Changes to test/triggerupfrom.test.
︙ | ︙ | |||
167 168 169 170 171 172 173 | (2,two)->(twelve,two) (4,four)->(fourteen,four) } finish_test | < | 167 168 169 170 171 172 173 | (2,two)->(twelve,two) (4,four)->(fourteen,four) } finish_test |
Changes to test/upfrom1.tcl.
︙ | ︙ | |||
108 109 110 111 112 113 114 | } errorsql_test 2.3.2 { UPDATE t5 AS apples SET b=1 FROM t5 AS apples; } finish_test | < | 108 109 110 111 112 113 114 | } errorsql_test 2.3.2 { UPDATE t5 AS apples SET b=1 FROM t5 AS apples; } finish_test |
Changes to test/upfrom2.test.
︙ | ︙ | |||
363 364 365 366 367 368 369 | } { do_catchsql_test 5.$tn $update \ "1 {target object/alias may not appear in FROM clause: $nm}" } finish_test | < < | 363 364 365 366 367 368 369 | } { do_catchsql_test 5.$tn $update \ "1 {target object/alias may not appear in FROM clause: $nm}" } finish_test |
Changes to test/upfrom3.test.
︙ | ︙ | |||
255 256 257 258 259 260 261 | SELECT * FROM c1 } {a 1 b 12 c 112} }] } finish_test | < | 255 256 257 258 259 260 261 | SELECT * FROM c1 } {a 1 b 12 c 112} }] } finish_test |
Changes to test/upfromfault.test.
︙ | ︙ | |||
133 134 135 136 137 138 139 | error "unexpected result: $res" } } } finish_test | < | 133 134 135 136 137 138 139 | error "unexpected result: $res" } } } finish_test |
Changes to test/upsert1.test.
︙ | ︙ | |||
126 127 128 129 130 131 132 | DELETE FROM t1; INSERT OR IGNORE INTO t1(a) VALUES('1'),(1) ON CONFLICT(a) DO NOTHING; PRAGMA integrity_check; } {ok} # 2018-08-14 # Ticket https://www.sqlite.org/src/info/908f001483982c43 | | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | DELETE FROM t1; INSERT OR IGNORE INTO t1(a) VALUES('1'),(1) ON CONFLICT(a) DO NOTHING; PRAGMA integrity_check; } {ok} # 2018-08-14 # Ticket https://www.sqlite.org/src/info/908f001483982c43 # If there are multiple uniqueness constraints, the UPSERT should fire # if the one constraint it targets fails, regardless of whether or not # the other constraints pass or fail. In other words, the UPSERT constraint # should be tested first. # do_execsql_test upsert1-700 { DROP TABLE t1; CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT, d INT, e INT); |
︙ | ︙ |
Changes to test/wal2.test.
︙ | ︙ | |||
451 452 453 454 455 456 457 | # locking_mode=exclusive. # # wal2-6.4.*: Check that xShmLock calls are omitted in exclusive locking # mode. # # wal2-6.5.*: # | | | 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | # locking_mode=exclusive. # # wal2-6.4.*: Check that xShmLock calls are omitted in exclusive locking # mode. # # wal2-6.5.*: # # wal2-6.6.*: Check that if the xShmLock() to reacquire a WAL read-lock when # exiting exclusive mode fails (i.e. SQLITE_IOERR), then the # connection silently remains in exclusive mode. # do_test wal2-6.1.1 { forcedelete test.db test.db-wal test.db-journal sqlite3 db test.db execsql { |
︙ | ︙ |
Changes to test/wal_common.tcl.
︙ | ︙ | |||
85 86 87 88 89 90 91 | upvar $hdrvar hdr set c1 0 set c2 0 wal_cksum_intlist c1 c2 [lrange $hdr 0 9] lset hdr 10 $c1 lset hdr 11 $c2 } | < < | 85 86 87 88 89 90 91 | upvar $hdrvar hdr set c1 0 set c2 0 wal_cksum_intlist c1 c2 [lrange $hdr 0 9] lset hdr 10 $c1 lset hdr 11 $c2 } |
Changes to test/walsetlk.test.
︙ | ︙ | |||
191 192 193 194 195 196 197 | } {wal} do_test 3.1 { list [catch { db2 eval {BEGIN EXCLUSIVE} } msg] $msg } {1 {database is locked}} finish_test | < | 191 192 193 194 195 196 197 | } {wal} do_test 3.1 { list [catch { db2 eval {BEGIN EXCLUSIVE} } msg] $msg } {1 {database is locked}} finish_test |
Changes to test/wapp.tcl.
︙ | ︙ | |||
338 339 340 341 342 343 344 | append res "$p:$ln: unsafe \"wapp-$cx\" call: \"[string trim $x]\"\n" } } } return $res } | | | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | append res "$p:$ln: unsafe \"wapp-$cx\" call: \"[string trim $x]\"\n" } } } return $res } # Return a string that describes the current environment. Applications # might find this useful for debugging. # proc wapp-debug-env {} { global wapp set out {} foreach var [lsort [dict keys $wapp]] { if {[string index $var 0]=="."} continue |
︙ | ︙ |
Changes to test/wapptest.tcl.
︙ | ︙ | |||
890 891 892 893 894 895 896 | if {$G(noui)==0} { wapp-start $lWappArg } else { wapptest_run do_some_stuff vwait forever } | < | 890 891 892 893 894 895 896 | if {$G(noui)==0} { wapp-start $lWappArg } else { wapptest_run do_some_stuff vwait forever } |
Changes to test/win32lock.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2011 July 11 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 2011 July 11 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is recovery from transient mandatory locks # that sometimes appear on database files due to anti-virus software. # if {$tcl_platform(platform)!="windows"} return set testdir [file dirname $argv0] source $testdir/tester.tcl |
︙ | ︙ |
Changes to test/window2.tcl.
︙ | ︙ | |||
486 487 488 489 490 491 492 | execsql_test 7.3 { SELECT c, sum(c) OVER win1 FROM t1 WINDOW win1 AS (ORDER BY 1) } finish_test | < < | 486 487 488 489 490 491 492 | execsql_test 7.3 { SELECT c, sum(c) OVER win1 FROM t1 WINDOW win1 AS (ORDER BY 1) } finish_test |
Changes to test/window3.tcl.
︙ | ︙ | |||
356 357 358 359 360 361 362 | FILTER (WHERE a%2=0) OVER win FROM t2 WINDOW win AS (PARTITION BY (a%10) ORDER BY a $window) " } finish_test | < | 356 357 358 359 360 361 362 | FILTER (WHERE a%2=0) OVER win FROM t2 WINDOW win AS (PARTITION BY (a%10) ORDER BY a $window) " } finish_test |
Changes to test/window4.tcl.
︙ | ︙ | |||
417 418 419 420 421 422 423 | SELECT (SELECT avg(a) UNION SELECT min(a) OVER ()) FROM t2 GROUP BY a ORDER BY 1 } finish_test | < | 417 418 419 420 421 422 423 | SELECT (SELECT avg(a) UNION SELECT min(a) OVER ()) FROM t2 GROUP BY a ORDER BY 1 } finish_test |
Changes to test/window7.tcl.
︙ | ︙ | |||
84 85 86 87 88 89 90 | 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; } finish_test | < | 84 85 86 87 88 89 90 | 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; } finish_test |
Changes to test/window8.tcl.
︙ | ︙ | |||
417 418 419 420 421 422 423 | ); " } finish_test | < < | 417 418 419 420 421 422 423 | ); " } finish_test |
Changes to test/windowerr.tcl.
︙ | ︙ | |||
65 66 67 68 69 70 71 | } errorsql_test 3.3 { SELECT row_number(a) OVER () FROM t1; } finish_test | < | 65 66 67 68 69 70 71 | } errorsql_test 3.3 { SELECT row_number(a) OVER () FROM t1; } finish_test |
Changes to test/without_rowid1.test.
︙ | ︙ | |||
359 360 361 362 363 364 365 | CREATE TABLE t1(x INTEGER PRIMARY KEY UNIQUE, b) WITHOUT ROWID; CREATE INDEX t1x ON t1(x); INSERT INTO t1(x,b) VALUES('funny','buffalo'); SELECT type, name, '|' FROM sqlite_master; } {table t1 | index t1x |} # 2018-04-05: OSSFuzz found that the following was accessing an | | | 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 | CREATE TABLE t1(x INTEGER PRIMARY KEY UNIQUE, b) WITHOUT ROWID; CREATE INDEX t1x ON t1(x); INSERT INTO t1(x,b) VALUES('funny','buffalo'); SELECT type, name, '|' FROM sqlite_master; } {table t1 | index t1x |} # 2018-04-05: OSSFuzz found that the following was accessing an # uninitialized memory cell. Which was not actually causing a # malfunction, but does cause an assert() to fail. # do_execsql_test 9.0 { CREATE TABLE t2(b, c, PRIMARY KEY(b,c)) WITHOUT ROWID; CREATE UNIQUE INDEX t2b ON t2(b); UPDATE t2 SET b=1 WHERE b=''; } |
︙ | ︙ |
Changes to tool/genfkey.README.
︙ | ︙ | |||
59 60 61 62 63 64 65 | row is being updated). SET NULL: Instead of throwing an exception, the foreign key fields of all corresponding child table rows are set to NULL. LIMITATIONS | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | row is being updated). SET NULL: Instead of throwing an exception, the foreign key fields of all corresponding child table rows are set to NULL. LIMITATIONS Apart from those limitations described above: * Implicit mapping to composite primary keys is not supported. If a parent table has a composite primary key, then any child table that refers to it must explicitly map each column. For example, given the following definition of table "parent": CREATE TABLE parent(a, b, c, PRIMARY KEY(a, b)); |
︙ | ︙ | |||
104 105 106 107 108 109 110 | a foreign key that refers to columns in a parent table that are not guaranteed to be unique. If such errors are found and the --ignore-errors option was not present, a message for each one is printed to stderr and no further processing takes place. If errors are found and the --ignore-errors option is passed, then no error messages are printed. No "CREATE TRIGGER" statements are generated | | | < | 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 | a foreign key that refers to columns in a parent table that are not guaranteed to be unique. If such errors are found and the --ignore-errors option was not present, a message for each one is printed to stderr and no further processing takes place. If errors are found and the --ignore-errors option is passed, then no error messages are printed. No "CREATE TRIGGER" statements are generated for foreign-key definitions that contained errors, they are silently ignored by subsequent processing. All triggers generated by this command have names that match the pattern "genfkey*". Unless the --no-drop option is specified, then the program also generates a "DROP TRIGGER" statement for each trigger that exists in the database with a name that matches this pattern. This allows the program to be used to upgrade a database schema for which foreign key triggers have already been installed (i.e. after new tables are created or existing tables dropped). Finally, a series of SQL trigger definitions (CREATE TRIGGER statements) that implement the foreign key constraints found in the database schema are generated. If the --exec option was passed, then all generated SQL is immediately executed on the database. Otherwise, the generated SQL strings are output in the same way as the results of SELECT queries are. Normally, this means they will be printed to stdout, but this can be configured using other dot-commands (i.e. ".output"). The simplest way to activate the foreign key definitions in a database is simply to open it using the shell tool and enter the command ".genfkey --exec": sqlite> .genfkey --exec |
Changes to tool/lemon.c.
︙ | ︙ | |||
1023 1024 1025 1026 1027 1028 1029 | struct config *cfp; /* For looping thru the config closure of "stp" */ struct config *bcfp; /* For the inner loop on config closure of "stp" */ struct config *newcfg; /* */ struct symbol *sp; /* Symbol following the dot in configuration "cfp" */ struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */ struct state *newstp; /* A pointer to a successor state */ | | | 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 | struct config *cfp; /* For looping thru the config closure of "stp" */ struct config *bcfp; /* For the inner loop on config closure of "stp" */ struct config *newcfg; /* */ struct symbol *sp; /* Symbol following the dot in configuration "cfp" */ struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */ struct state *newstp; /* A pointer to a successor state */ /* Each configuration becomes complete after it contributes to a successor ** state. Initially, all configurations are incomplete */ for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE; /* Loop through all configurations of the state "stp" */ for(cfp=stp->cfp; cfp; cfp=cfp->next){ if( cfp->status==COMPLETE ) continue; /* Already used by inner loop */ if( cfp->dot>=cfp->rp->nrhs ) continue; /* Can't shift this config */ |
︙ | ︙ | |||
1539 1540 1541 1542 1543 1544 1545 | exit(1); } lemon_strcpy(*paz, z); for(z=*paz; *z && *z!='='; z++){} *z = 0; } | | | 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 | exit(1); } lemon_strcpy(*paz, z); for(z=*paz; *z && *z!='='; z++){} *z = 0; } /* Remember the name of the output directory */ static char *outputDir = NULL; static void handle_d_option(char *z){ outputDir = (char *) malloc( lemonStrlen(z)+1 ); if( outputDir==0 ){ fprintf(stderr,"out of memory\n"); exit(1); |
︙ | ︙ | |||
1883 1884 1885 1886 1887 1888 1889 | ** Inputs: ** list: Pointer to a singly-linked list of structures. ** next: Pointer to pointer to the second element of the list. ** cmp: A comparison function. ** ** Return Value: ** A pointer to the head of a sorted list containing the elements | | | 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 | ** Inputs: ** list: Pointer to a singly-linked list of structures. ** next: Pointer to pointer to the second element of the list. ** cmp: A comparison function. ** ** Return Value: ** A pointer to the head of a sorted list containing the elements ** originally in list. ** ** Side effects: ** The "next" pointers for elements in list are changed. */ #define LISTSIZE 30 static char *msort( char *list, |
︙ | ︙ | |||
3507 3508 3509 3510 3511 3512 3513 | fprintf(fp,"\n"); } fclose(fp); return; } /* Search for the file "name" which is in the same directory as | | | 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 | fprintf(fp,"\n"); } fclose(fp); return; } /* Search for the file "name" which is in the same directory as ** the executable */ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) { const char *pathlist; char *pathbufptr; char *pathbuf; char *path,*cp; char c; |
︙ | ︙ | |||
3562 3563 3564 3565 3566 3567 3568 | */ PRIVATE int compute_action(struct lemon *lemp, struct action *ap) { int act; switch( ap->type ){ case SHIFT: act = ap->x.stp->statenum; break; case SHIFTREDUCE: { | | | 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 | */ PRIVATE int compute_action(struct lemon *lemp, struct action *ap) { int act; switch( ap->type ){ case SHIFT: act = ap->x.stp->statenum; break; case SHIFTREDUCE: { /* Since a SHIFT is inherent after a prior REDUCE, convert any ** SHIFTREDUCE action with a nonterminal on the LHS into a simple ** REDUCE action: */ if( ap->sp->index>=lemp->nterminal ){ act = lemp->minReduce + ap->x.rp->iRule; }else{ act = lemp->minShiftReduce + ap->x.rp->iRule; } |
︙ | ︙ | |||
3851 3852 3853 3854 3855 3856 3857 | if( rp->nrhs==0 ){ /* If there are no RHS symbols, then writing directly to the LHS is ok */ lhsdirect = 1; }else if( rp->rhsalias[0]==0 ){ /* The left-most RHS symbol has no value. LHS direct is ok. But | | | 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 | if( rp->nrhs==0 ){ /* If there are no RHS symbols, then writing directly to the LHS is ok */ lhsdirect = 1; }else if( rp->rhsalias[0]==0 ){ /* The left-most RHS symbol has no value. LHS direct is ok. But ** we have to call the destructor on the RHS symbol first. */ lhsdirect = 1; if( has_destructor(rp->rhs[0],lemp) ){ append_str(0,0,0,0); append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0, rp->rhs[0]->index,1-rp->nrhs); rp->codePrefix = Strsafe(append_str(0,0,0,0)); rp->noCode = 0; |
︙ | ︙ | |||
4811 4812 4813 4814 4815 4816 4817 | tplt_print(out,lemp,lemp->overflow,&lineno); tplt_xfer(lemp->name,in,out,&lineno); /* Generate the tables of rule information. yyRuleInfoLhs[] and ** yyRuleInfoNRhs[]. ** ** Note: This code depends on the fact that rules are number | | | 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 | tplt_print(out,lemp,lemp->overflow,&lineno); tplt_xfer(lemp->name,in,out,&lineno); /* Generate the tables of rule information. yyRuleInfoLhs[] and ** yyRuleInfoNRhs[]. ** ** Note: This code depends on the fact that rules are number ** sequentially beginning with 0. */ for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ fprintf(out," %4d, /* (%d) ", rp->lhs->index, i); rule_print(out, rp); fprintf(out," */\n"); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); |
︙ | ︙ |
Changes to tool/logest.c.
︙ | ︙ | |||
107 108 109 110 111 112 113 | static void showHelp(const char *zArgv0){ printf("Usage: %s ARGS...\n", zArgv0); printf("Arguments:\n" " NUM Convert NUM from integer to LogEst and push onto the stack\n" " ^NUM Interpret NUM as a LogEst and push onto stack\n" " x Multiple the top two elements of the stack\n" " + Add the top two elements of the stack\n" | | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | static void showHelp(const char *zArgv0){ printf("Usage: %s ARGS...\n", zArgv0); printf("Arguments:\n" " NUM Convert NUM from integer to LogEst and push onto the stack\n" " ^NUM Interpret NUM as a LogEst and push onto stack\n" " x Multiple the top two elements of the stack\n" " + Add the top two elements of the stack\n" " dup Duplicate the top element on the stack\n" " inv Take the reciprocal of the top of stack. N = 1/N.\n" " log Find the LogEst of the number on top of stack\n" " nlogn Compute NlogN where N is the top of stack\n" ); exit(1); } |
︙ | ︙ |
Changes to tool/mkctimec.tcl.
︙ | ︙ | |||
303 304 305 306 307 308 309 | #endif }] } foreach o [lsort [array names options]] { puts [string trim $options($o)] } | < < | 303 304 305 306 307 308 309 | #endif }] } foreach o [lsort [array names options]] { puts [string trim $options($o)] } |
Changes to tool/mkshellc.tcl.
︙ | ︙ | |||
16 17 18 19 20 21 22 | ** SQLite source tree at tool/mkshellc.tcl. That script combines source ** code from various constituent source files of SQLite into this single ** "shell.c" file used to implement the SQLite command-line shell. ** ** Most of the code found below comes from the "src/shell.c.in" file in ** the canonical SQLite source tree. That main file contains "INCLUDE" ** lines that specify other files in the canonical source tree that are | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ** SQLite source tree at tool/mkshellc.tcl. That script combines source ** code from various constituent source files of SQLite into this single ** "shell.c" file used to implement the SQLite command-line shell. ** ** Most of the code found below comes from the "src/shell.c.in" file in ** the canonical SQLite source tree. That main file contains "INCLUDE" ** lines that specify other files in the canonical source tree that are ** inserted to generate this complete program source file. ** ** The code from multiple files is combined into this single "shell.c" ** source file to help make the command-line program easier to compile. ** ** To modify this program, get a copy of the canonical SQLite source tree, ** edit the src/shell.c.in" and/or some of the other files that are included ** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script. |
︙ | ︙ |
Changes to tool/mkspeedsql.tcl.
︙ | ︙ | |||
12 13 14 15 16 17 18 | # # $Id: mkspeedsql.tcl,v 1.1 2008/10/09 17:57:34 drh Exp $ # # Set a uniform random seed expr srand(0) | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # # $Id: mkspeedsql.tcl,v 1.1 2008/10/09 17:57:34 drh Exp $ # # Set a uniform random seed expr srand(0) # The number_name procedure below converts its argument (an integer) # into a string which is the English-language name for that number. # # Example: # # puts [number_name 123] -> "one hundred twenty three" # set ones {zero one two three four five six seven eight nine |
︙ | ︙ |
Changes to tool/mksqlite3internalh.tcl.
︙ | ︙ | |||
88 89 90 91 92 93 94 | set nstar [expr {60 - $n}] set stars [string range $s78 0 $nstar] puts $out "/************** $text $stars/" } # Read the source file named $filename and write it into the # sqlite3.c output file. If any #include statements are seen, | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | set nstar [expr {60 - $n}] set stars [string range $s78 0 $nstar] puts $out "/************** $text $stars/" } # Read the source file named $filename and write it into the # sqlite3.c output file. If any #include statements are seen, # process them appropriately. # proc copy_file {filename} { global seen_hdr available_hdr out set tail [file tail $filename] section_comment "Begin file $tail" set in [open $filename r] while {![eof $in]} { |
︙ | ︙ |
Changes to tool/omittest.tcl.
︙ | ︙ | |||
9 10 11 12 13 14 15 | The default value for ::MAKEFILE is "../Makefile.linux.gcc". If -skip_run option is given then only the compile part is attempted. This script builds the testfixture program and runs the SQLite test suite once with each SQLITE_OMIT_ option defined and then once with all options | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | The default value for ::MAKEFILE is "../Makefile.linux.gcc". If -skip_run option is given then only the compile part is attempted. This script builds the testfixture program and runs the SQLite test suite once with each SQLITE_OMIT_ option defined and then once with all options defined together. Each run is performed in a separate directory created as a sub-directory of the current directory by the script. The output of the build is saved in <sub-directory>/build.log. The output of the test-suite is saved in <sub-directory>/test.log. Almost any SQLite makefile (except those generated by configure - see below) should work. The following properties are required: |
︙ | ︙ |
Changes to tool/run-speed-test.sh.
1 2 3 4 5 6 7 | #!/bin/bash # # This is a template for a script used for day-to-day size and # performance monitoring of SQLite. Typical usage: # # sh run-speed-test.sh trunk # Baseline measurement of trunk # sh run-speed-test.sh x1 # Measure some experimental change | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/bin/bash # # This is a template for a script used for day-to-day size and # performance monitoring of SQLite. Typical usage: # # sh run-speed-test.sh trunk # Baseline measurement of trunk # sh run-speed-test.sh x1 # Measure some experimental change # fossil test-diff --tk cout-trunk.txt cout-x1.txt # View changes # # There are multiple output files, all with a base name given by # the first argument: # # summary-$BASE.txt # Copy of standard output # cout-$BASE.txt # cachegrind output # explain-$BASE.txt # EXPLAIN listings (only with --explain) |
︙ | ︙ |
Changes to tool/speed-check.sh.
1 2 3 4 5 6 7 | #!/bin/bash # # This is a template for a script used for day-to-day size and # performance monitoring of SQLite. Typical usage: # # sh run-speed-test.sh trunk # Baseline measurement of trunk # sh run-speed-test.sh x1 # Measure some experimental change | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/bin/bash # # This is a template for a script used for day-to-day size and # performance monitoring of SQLite. Typical usage: # # sh run-speed-test.sh trunk # Baseline measurement of trunk # sh run-speed-test.sh x1 # Measure some experimental change # fossil test-diff --tk cout-trunk.txt cout-x1.txt # View changes # # There are multiple output files, all with a base name given by # the first argument: # # summary-$BASE.txt # Copy of standard output # cout-$BASE.txt # cachegrind output # explain-$BASE.txt # EXPLAIN listings (only with --explain) |
︙ | ︙ |
Changes to tool/sqldiff.c.
︙ | ︙ | |||
1527 1528 1529 1530 1531 1532 1533 | } } /* ** Generate a CHANGESET for all differences from main.zTab to aux.zTab. */ static void changeset_one_table(const char *zTab, FILE *out){ | | | 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 | } } /* ** Generate a CHANGESET for all differences from main.zTab to aux.zTab. */ static void changeset_one_table(const char *zTab, FILE *out){ sqlite3_stmt *pStmt; /* SQL statement */ char *zId = safeId(zTab); /* Escaped name of the table */ char **azCol = 0; /* List of escaped column names */ int nCol = 0; /* Number of columns */ int *aiFlg = 0; /* 0 if column is not part of PK */ int *aiPk = 0; /* Column numbers for each PK column */ int nPk = 0; /* Number of PRIMARY KEY columns */ Str sql; /* SQL for the diff query */ |
︙ | ︙ |